Avoid initMainThread() except on vxworks
Move isOkToBlock tracking to osdThread. Targets except vxworks can store this flag in epicsThreadOSD. Continue to use TLS w/ vxWorks. Note that setting of isOkToBlock for "main" thread becomes lazy.
This commit is contained in:

committed by
Andrew Johnson

parent
9f788996dc
commit
48ebe2c64e
@ -339,32 +339,6 @@ void epicsThread :: show ( unsigned level ) const throw ()
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
static epicsThreadOnceId okToBlockOnce = EPICS_THREAD_ONCE_INIT;
|
||||
epicsThreadPrivateId okToBlockPrivate;
|
||||
static const int okToBlockNo = 0;
|
||||
static const int okToBlockYes = 1;
|
||||
|
||||
static void epicsThreadOnceIdInit(void *)
|
||||
{
|
||||
okToBlockPrivate = epicsThreadPrivateCreate();
|
||||
}
|
||||
|
||||
int epicsStdCall epicsThreadIsOkToBlock(void)
|
||||
{
|
||||
const int *pokToBlock;
|
||||
epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL);
|
||||
pokToBlock = (int *) epicsThreadPrivateGet(okToBlockPrivate);
|
||||
return (pokToBlock ? *pokToBlock : 0);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
|
||||
{
|
||||
const int *pokToBlock;
|
||||
epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL);
|
||||
pokToBlock = (isOkToBlock) ? &okToBlockYes : &okToBlockNo;
|
||||
epicsThreadPrivateSet(okToBlockPrivate, (void *)pokToBlock);
|
||||
}
|
||||
|
||||
epicsThreadId epicsStdCall epicsThreadMustCreate (
|
||||
const char *name, unsigned int priority, unsigned int stackSize,
|
||||
EPICSTHREADFUNC funptr,void *parm)
|
||||
@ -375,12 +349,3 @@ extern "C" {
|
||||
return id;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
static epicsThreadId initMainThread(void) {
|
||||
epicsThreadId main = epicsThreadGetIdSelf();
|
||||
epicsThreadSetOkToBlock(1);
|
||||
return main;
|
||||
}
|
||||
|
||||
// Ensure the main thread gets a unique ID and allows blocking I/O
|
||||
epicsThreadId epicsThreadMainId = initMainThread();
|
||||
|
@ -37,6 +37,7 @@ typedef struct epicsThreadOSD {
|
||||
int isRealTimeScheduled;
|
||||
int isOnThreadList;
|
||||
int isRunning;
|
||||
int isOkToBlock;
|
||||
unsigned int osiPriority;
|
||||
int joinable;
|
||||
char name[1]; /* actually larger */
|
||||
|
@ -55,6 +55,7 @@ struct taskVar {
|
||||
int refcnt;
|
||||
int joinable;
|
||||
int isRunning;
|
||||
int isOkToBlock;
|
||||
EPICSTHREADFUNC funptr;
|
||||
void *parm;
|
||||
unsigned int threadVariableCapacity;
|
||||
@ -219,7 +220,7 @@ void epicsThreadExitMain (void)
|
||||
|
||||
static rtems_status_code
|
||||
setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr,
|
||||
void *parm, int joinable)
|
||||
void *parm, int joinable, int isOkToBlock)
|
||||
{
|
||||
struct taskVar *v;
|
||||
uint32_t note;
|
||||
@ -235,6 +236,7 @@ setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr,
|
||||
v->threadVariableCapacity = 0;
|
||||
v->threadVariables = NULL;
|
||||
v->isRunning = 1;
|
||||
v->isOkToBlock = isOkToBlock;
|
||||
if (joinable) {
|
||||
char c[3] = {0,0,0};
|
||||
strncpy(c, v->name, 3);
|
||||
@ -284,7 +286,7 @@ epicsThreadInit (void)
|
||||
epicsMutexOsdPrepare(&taskVarMutex);
|
||||
epicsMutexOsdPrepare(&onceMutex);
|
||||
rtems_task_ident (RTEMS_SELF, 0, &tid);
|
||||
if(setThreadInfo (tid, "_main_", NULL, NULL, 0) != RTEMS_SUCCESSFUL)
|
||||
if(setThreadInfo (tid, "_main_", NULL, NULL, 0, 1) != RTEMS_SUCCESSFUL)
|
||||
cantProceed("epicsThreadInit() unable to setup _main_");
|
||||
osdThreadHooksRunMain((epicsThreadId)tid);
|
||||
initialized = 1;
|
||||
@ -338,7 +340,7 @@ epicsThreadCreateOpt (
|
||||
name, rtems_status_text(sc));
|
||||
return 0;
|
||||
}
|
||||
sc = setThreadInfo (tid, name, funptr, parm, opts->joinable);
|
||||
sc = setThreadInfo (tid, name, funptr, parm, opts->joinable, 0);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
errlogPrintf ("epicsThreadCreate create failure during setup for %s: %s\n",
|
||||
name, rtems_status_text(sc));
|
||||
@ -870,3 +872,27 @@ LIBCOM_API int epicsThreadGetCPUs(void)
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int epicsStdCall epicsThreadIsOkToBlock(void)
|
||||
{
|
||||
uint32_t note = 0;
|
||||
struct taskVar *v;
|
||||
|
||||
rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e);
|
||||
v = (void *)note;
|
||||
|
||||
return v && v->isOkToBlock;
|
||||
}
|
||||
|
||||
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
|
||||
{
|
||||
uint32_t note = 0;
|
||||
struct taskVar *v;
|
||||
|
||||
rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e);
|
||||
v = (void *)note;
|
||||
|
||||
if(v)
|
||||
v->isOkToBlock = !!isOkToBlock;
|
||||
}
|
||||
|
@ -103,6 +103,7 @@ typedef struct epicsThreadOSD {
|
||||
char isSuspended;
|
||||
int joinable;
|
||||
int isRunning;
|
||||
int isOkToBlock;
|
||||
HANDLE timer; /* waitable timer */
|
||||
} win32ThreadParam;
|
||||
|
||||
@ -586,6 +587,7 @@ static win32ThreadParam * epicsThreadImplicitCreate ( void )
|
||||
|
||||
pParm->handle = handle;
|
||||
pParm->id = id;
|
||||
pParm->isOkToBlock = 1;
|
||||
win32ThreadPriority = GetThreadPriority ( pParm->handle );
|
||||
assert ( win32ThreadPriority != THREAD_PRIORITY_ERROR_RETURN );
|
||||
pParm->epicsPriority = epicsThreadGetOsiPriorityValue ( win32ThreadPriority );
|
||||
@ -1224,3 +1226,17 @@ void testPriorityMapping ()
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int epicsStdCall epicsThreadIsOkToBlock(void)
|
||||
{
|
||||
struct epicsThreadOSD *pthreadInfo = epicsThreadGetIdSelf();
|
||||
|
||||
return(pthreadInfo->isOkToBlock);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
|
||||
{
|
||||
struct epicsThreadOSD *pthreadInfo = epicsThreadGetIdSelf();
|
||||
|
||||
pthreadInfo->isOkToBlock = !!isOkToBlock;
|
||||
}
|
||||
|
@ -665,6 +665,7 @@ static epicsThreadOSD *createImplicit(void)
|
||||
assert(pthreadInfo);
|
||||
pthreadInfo->tid = tid;
|
||||
pthreadInfo->osiPriority = 0;
|
||||
pthreadInfo->isOkToBlock = 1;
|
||||
|
||||
#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0
|
||||
if(pthread_getschedparam(tid,&pthreadInfo->schedPolicy,&pthreadInfo->schedParam) == 0) {
|
||||
@ -1085,3 +1086,17 @@ LIBCOM_API int epicsThreadGetCPUs(void)
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int epicsStdCall epicsThreadIsOkToBlock(void)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo = epicsThreadGetIdSelf();
|
||||
|
||||
return(pthreadInfo->isOkToBlock);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
|
||||
{
|
||||
epicsThreadOSD *pthreadInfo = epicsThreadGetIdSelf();
|
||||
|
||||
pthreadInfo->isOkToBlock = !!isOkToBlock;
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ typedef struct epicsThreadOSD {
|
||||
int isRealTimeScheduled;
|
||||
int isOnThreadList;
|
||||
int isRunning;
|
||||
int isOkToBlock;
|
||||
unsigned int osiPriority;
|
||||
int joinable;
|
||||
char name[1]; /* actually larger */
|
||||
|
@ -127,7 +127,8 @@ static void epicsThreadInit(void)
|
||||
taskIdListSize = ID_LIST_CHUNK;
|
||||
atRebootRegister();
|
||||
ALLOT_JOIN(0);
|
||||
done = 1;
|
||||
done = 1; /* avoids recursive call */
|
||||
epicsThreadSetOkToBlock(1);
|
||||
}
|
||||
lock = 0;
|
||||
}
|
||||
@ -577,3 +578,30 @@ LIBCOM_API int epicsThreadGetCPUs(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static epicsThreadOnceId okToBlockOnce = EPICS_THREAD_ONCE_INIT;
|
||||
static epicsThreadPrivateId okToBlockPrivate;
|
||||
static const int okToBlockNo = 0;
|
||||
static const int okToBlockYes = 1;
|
||||
|
||||
static void epicsThreadOnceIdInit(void *not_used)
|
||||
{
|
||||
okToBlockPrivate = epicsThreadPrivateCreate();
|
||||
}
|
||||
|
||||
int epicsStdCall epicsThreadIsOkToBlock(void)
|
||||
{
|
||||
const int *pokToBlock;
|
||||
epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL);
|
||||
pokToBlock = (int *) epicsThreadPrivateGet(okToBlockPrivate);
|
||||
return (pokToBlock ? *pokToBlock : 0);
|
||||
}
|
||||
|
||||
void epicsStdCall epicsThreadSetOkToBlock(int isOkToBlock)
|
||||
{
|
||||
const int *pokToBlock;
|
||||
epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL);
|
||||
pokToBlock = (isOkToBlock) ? &okToBlockYes : &okToBlockNo;
|
||||
epicsThreadPrivateSet(okToBlockPrivate, (void *)pokToBlock);
|
||||
}
|
||||
|
Reference in New Issue
Block a user