Replace epicsThreadOptsDefaults() with EPICS_THREAD_OPTS_INIT

The epicsThreadCreate() routines now interpose calls to
epicsThreadGetStackSize() if an enum value is passed.
This commit is contained in:
Andrew Johnson
2019-07-02 17:27:27 -05:00
parent 4b77d5e1c9
commit fbf62189cb
10 changed files with 95 additions and 86 deletions

View File

@@ -229,8 +229,8 @@ static void asCaTask(void)
void asCaStart(void)
{
epicsThreadOpts opts;
epicsThreadOptsDefaults(&opts);
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackBig);
opts.priority = epicsThreadPriorityScanLow - 3;
opts.joinable = 1;

View File

@@ -265,8 +265,8 @@ void dbCaShutdown(void)
static void dbCaLinkInitImpl(int isolate)
{
epicsThreadOpts opts;
epicsThreadOptsDefaults(&opts);
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackBig);
opts.priority = epicsThreadPriorityMedium;
opts.joinable = 1;

View File

@@ -1056,9 +1056,8 @@ int db_start_events (
void *init_func_arg, unsigned osiPriority )
{
struct event_user * const evUser = (struct event_user *) ctx;
epicsThreadOpts opts;
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
epicsThreadOptsDefaults(&opts);
opts.stackSize = epicsThreadGetStackSize(epicsThreadStackMedium);
opts.priority = osiPriority;
opts.joinable = 1;

View File

@@ -35,7 +35,7 @@ epicsThreadId epicsShareAPI epicsThreadCreate (
const char * name, unsigned int priority, unsigned int stackSize,
EPICSTHREADFUNC funptr,void * parm )
{
epicsThreadOpts opts;
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.priority = priority;
opts.stackSize = stackSize;
opts.joinable = 0;
@@ -202,11 +202,10 @@ epicsThread::epicsThread (
epicsThreadRunable & runableIn, const char * pName,
unsigned stackSize, unsigned priority ) :
runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ),
begin ( false ), cancel ( false ), terminated ( false )
, joined(false)
begin ( false ), cancel ( false ), terminated ( false ),
joined ( false )
{
epicsThreadOpts opts;
epicsThreadOptsDefaults(&opts);
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
opts.stackSize = stackSize;
opts.priority = priority;
opts.joinable = 1;

View File

@@ -84,9 +84,8 @@ epicsShareFunc void epicsShareAPI epicsThreadExitMain(void);
typedef struct epicsThreadOpts {
/** Thread priority in OSI range (cf. epicsThreadPriority*) */
unsigned int priority;
/** Thread stack size, as returned by epicsThreadGetStackSize().
*
* @warning Do not pass enum epicsThreadStackSizeClass directly!
/** Thread stack size, either in bytes for this architecture or
* an enum epicsThreadStackSizeClass value.
*/
unsigned int stackSize;
/** Should thread be joinable? (default (0) is not joinable).
@@ -95,8 +94,14 @@ typedef struct epicsThreadOpts {
unsigned int joinable;
} epicsThreadOpts;
/** Fill in target specific default values. */
epicsShareFunc void epicsThreadOptsDefaults(epicsThreadOpts *opts);
/** Default initial values for epicsThreadOpts
* Applications should always use this macro to initialize an epicsThreadOpts
* structure. Additional fields may be added in the future, and the order of
* the fields might also change, thus code that assumes the above definition
* might break if these rules are not followed.
*/
#define EPICS_THREAD_OPTS_INIT { \
epicsThreadPriorityLow, epicsThreadStackMedium, 0}
/** @brief Allocate and start a new OS thread.
* @param name A name describing this thread. Appears in various log and error message.

View File

@@ -152,13 +152,6 @@ epicsThreadGetStackSize (epicsThreadStackSizeClass size)
return stackSize;
}
static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, 5000, 0};
void epicsThreadOptsDefaults(epicsThreadOpts *opts)
{
*opts = opts_default;
}
/*
* Ensure integrity of task variable list
*/
@@ -315,15 +308,22 @@ epicsThreadCreateOpt (
const char * name,
EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts )
{
unsigned int stackSize;
rtems_id tid;
rtems_status_code sc;
char c[4];
unsigned stackSize;
if(!opts) opts = &opts_default;
if (!initialized)
epicsThreadInit();
if (!opts) {
static const epicsThreadOpts opts_default = EPICS_THREAD_OPTS_INIT;
opts = &opts_default;
}
stackSize = opts->stackSize;
if (stackSize <= epicsThreadStackBig)
stackSize = epicsThreadGetStackSize(stackSize);
if (!initialized) epicsThreadInit();
if (stackSize < RTEMS_MINIMUM_STACK_SIZE) {
errlogPrintf ("Warning: epicsThreadCreate %s illegal stackSize %d\n",
name, stackSize);

View File

@@ -469,13 +469,6 @@ epicsShareFunc unsigned int epicsShareAPI
return stackSizeTable[stackSizeClass];
}
static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, STACK_SIZE(1), 0};
void epicsThreadOptsDefaults(epicsThreadOpts *opts)
{
*opts = opts_default;
}
void epicsThreadCleanupWIN32 ()
{
win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal ();
@@ -599,6 +592,7 @@ epicsThreadId epicsThreadCreateOpt (
{
win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal ();
win32ThreadParam * pParmWIN32;
unsigned int stackSize;
int osdPriority;
DWORD wstat;
BOOL bstat;
@@ -607,7 +601,13 @@ epicsThreadId epicsThreadCreateOpt (
return NULL;
}
if(!opts) opts = &opts_default;
if (!opts) {
static const epicsThreadOpts opts_default = EPICS_THREAD_OPTS_INIT;
opts = &opts_default;
}
stackSize = opts->stackSize;
if (stackSize <= epicsThreadStackBig)
stackSize = epicsThreadGetStackSize(stackSize);
pParmWIN32 = epicsThreadParmCreate ( pName );
if ( pParmWIN32 == 0 ) {
@@ -620,7 +620,7 @@ epicsThreadId epicsThreadCreateOpt (
{
unsigned threadId;
pParmWIN32->handle = (HANDLE) _beginthreadex (
0, opts->stackSize, epicsWin32ThreadEntry,
0, stackSize, epicsWin32ThreadEntry,
pParmWIN32,
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
& threadId );

View File

@@ -469,13 +469,6 @@ epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadSt
return 0;
#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/
}
static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, STACK_SIZE(1), 0};
void epicsThreadOptsDefaults(epicsThreadOpts *opts)
{
*opts = opts_default;
}
epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg)
{
@@ -519,48 +512,65 @@ epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*
}
epicsThreadId
epicsThreadCreateOpt (
const char * name,
epicsThreadCreateOpt(const char * name,
EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts )
{
unsigned int stackSize;
epicsThreadOSD *pthreadInfo;
int status;
sigset_t blockAllSig, oldSig;
if(!opts) opts = &opts_default;
epicsThreadInit();
assert(pcommonAttr);
if (!opts) {
static const epicsThreadOpts opts_default = EPICS_THREAD_OPTS_INIT;
opts = &opts_default;
}
stackSize = opts->stackSize;
if (stackSize <= epicsThreadStackBig)
stackSize = epicsThreadGetStackSize(stackSize);
sigfillset(&blockAllSig);
pthread_sigmask(SIG_SETMASK,&blockAllSig,&oldSig);
pthreadInfo = init_threadInfo(name,opts->priority,opts->stackSize,funptr,parm,opts->joinable);
if(pthreadInfo==0) return 0;
pthread_sigmask(SIG_SETMASK, &blockAllSig, &oldSig);
pthreadInfo = init_threadInfo(name, opts->priority, stackSize, funptr,
parm, opts->joinable);
if (pthreadInfo==0)
return 0;
pthreadInfo->isEpicsThread = 1;
setSchedulingPolicy(pthreadInfo,SCHED_FIFO);
setSchedulingPolicy(pthreadInfo, SCHED_FIFO);
pthreadInfo->isRealTimeScheduled = 1;
status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr,
start_routine,pthreadInfo);
if(status==EPERM){
status = pthread_create(&pthreadInfo->tid, &pthreadInfo->attr,
start_routine, pthreadInfo);
if (status==EPERM) {
/* Try again without SCHED_FIFO*/
free_threadInfo(pthreadInfo);
pthreadInfo = init_threadInfo(name,opts->priority,opts->stackSize,funptr,parm,opts->joinable);
if(pthreadInfo==0) return 0;
pthreadInfo = init_threadInfo(name, opts->priority, stackSize,
funptr, parm, opts->joinable);
if (pthreadInfo==0)
return 0;
pthreadInfo->isEpicsThread = 1;
status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr,
start_routine,pthreadInfo);
status = pthread_create(&pthreadInfo->tid, &pthreadInfo->attr,
start_routine, pthreadInfo);
}
checkStatusOnce(status,"pthread_create");
if(status) {
checkStatusOnce(status, "pthread_create");
if (status) {
free_threadInfo(pthreadInfo);
return 0;
}
status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL);
checkStatusOnce(status,"pthread_sigmask");
if(pthreadInfo->joinable) {
status = pthread_sigmask(SIG_SETMASK, &oldSig, NULL);
checkStatusOnce(status, "pthread_sigmask");
if (pthreadInfo->joinable) {
/* extra ref for epicsThreadMustJoin() */
epicsAtomicIncrIntT(&pthreadInfo->refcnt);
}
return(pthreadInfo);
return pthreadInfo;
}
/*

View File

@@ -150,13 +150,6 @@ unsigned int epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass)
return stackSizeTable[stackSizeClass];
}
static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, 4000*ARCH_STACK_FACTOR, 0};
void epicsThreadOptsDefaults(epicsThreadOpts *opts)
{
*opts = opts_default;
}
struct epicsThreadOSD {};
/* Strictly speaking this should be a WIND_TCB, but we only need it to
* be able to create an epicsThreadId that is guaranteed never to be
@@ -256,20 +249,27 @@ static void createFunction(EPICSTHREADFUNC func, void *parm)
epicsThreadId epicsThreadCreateOpt(const char * name,
EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts )
{
unsigned int stackSize;
int tid;
if (!opts)
opts = &opts_default;
epicsThreadInit();
if (opts->stackSize < 100) {
if (!opts) {
static const epicsThreadOpts opts_default = EPICS_THREAD_OPTS_INIT;
opts = &opts_default;
}
stackSize = opts->stackSize;
if (stackSize <= epicsThreadStackBig)
stackSize = epicsThreadGetStackSize(stackSize);
if (stackSize < 100) {
errlogPrintf("epicsThreadCreate %s illegal stackSize %d\n",
name, opts->stackSize);
name, stackSize);
return 0;
}
tid = taskCreate((char *)name,getOssPriorityValue(opts->priority),
TASK_FLAGS, opts->stackSize,
TASK_FLAGS, stackSize,
(FUNCPTR)createFunction, (int)funptr, (int)parm,
0,0,0,0,0,0,0,0);
if (tid == ERROR) {

View File

@@ -40,7 +40,7 @@ private:
};
myThread::myThread(int arg,const char *name) :
thread(*this,name,epicsThreadGetStackSize(epicsThreadStackSmall),50+arg),
thread(*this,name,epicsThreadStackSmall,50+arg),
argvalue(0)
{
argvalue = new int;
@@ -132,16 +132,14 @@ void joinTests(void *arg)
void testJoining()
{
epicsThreadOpts opts;
epicsThreadOptsDefaults(&opts);
opts.priority = 50;
opts.joinable = 1;
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
epicsEvent finished, trigger;
struct joinStuff stuff = {
&opts, &trigger, &finished
};
opts.priority = 50;
opts.joinable = 1;
epicsThreadCreateOpt("parent", &joinTests, &stuff, &opts);
// as selfjoin joins itself, we can't.
@@ -172,9 +170,8 @@ static void thread(void *arg)
static void testOkToBlock()
{
epicsThreadOpts opts = EPICS_THREAD_OPTS_INIT;
epicsThreadOpts opts;
epicsThreadOptsDefaults(&opts);
opts.priority = 50;
opts.joinable = 1;
@@ -190,7 +187,6 @@ static void testOkToBlock()
epicsThreadMustJoin(threadA);
testOk1(infoA.didSomething);
}