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:
Michael Davidsaver
2023-01-09 11:46:17 -08:00
committed by Andrew Johnson
parent 9f788996dc
commit 48ebe2c64e
7 changed files with 91 additions and 39 deletions

View File

@ -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();

View File

@ -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 */

View File

@ -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, &note);
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, &note);
v = (void *)note;
if(v)
v->isOkToBlock = !!isOkToBlock;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}