diff --git a/modules/libcom/src/osi/epicsThread.cpp b/modules/libcom/src/osi/epicsThread.cpp index 892d73de0..372806edb 100644 --- a/modules/libcom/src/osi/epicsThread.cpp +++ b/modules/libcom/src/osi/epicsThread.cpp @@ -31,6 +31,17 @@ using namespace std; +epicsThreadId epicsShareAPI epicsThreadCreate ( + const char * name, unsigned int priority, unsigned int stackSize, + EPICSTHREADFUNC funptr,void * parm ) +{ + epicsThreadOpts opts; + opts.priority = priority; + opts.stackSize = stackSize; + + return epicsThreadCreateOpt(name, funptr, parm, &opts); +} + epicsThreadRunable::~epicsThreadRunable () {} void epicsThreadRunable::run () {} void epicsThreadRunable::show ( unsigned int ) const {} diff --git a/modules/libcom/src/osi/epicsThread.h b/modules/libcom/src/osi/epicsThread.h index 84b2c4788..d0879a8eb 100644 --- a/modules/libcom/src/osi/epicsThread.h +++ b/modules/libcom/src/osi/epicsThread.h @@ -65,6 +65,22 @@ epicsShareFunc void epicsThreadRealtimeLock(void); 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! + */ + unsigned int stackSize; +} epicsThreadOpts; + +epicsShareFunc void epicsThreadOptsDefaults(epicsThreadOpts *opts); + +epicsShareFunc epicsThreadId epicsThreadCreateOpt ( + const char * name, + EPICSTHREADFUNC funptr, void * parm, + const epicsThreadOpts *opts ); epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate ( const char * name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr,void * parm ); diff --git a/modules/libcom/src/osi/os/RTEMS/osdThread.c b/modules/libcom/src/osi/os/RTEMS/osdThread.c index 769e95820..7b478df65 100644 --- a/modules/libcom/src/osi/os/RTEMS/osdThread.c +++ b/modules/libcom/src/osi/os/RTEMS/osdThread.c @@ -148,6 +148,13 @@ epicsThreadGetStackSize (epicsThreadStackSizeClass size) return stackSize; } +static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, 5000}; + +void epicsThreadOptsDefaults(epicsThreadOpts *opts) +{ + *opts = opts_default; +} + /* * Ensure integrity of task variable list */ @@ -263,13 +270,17 @@ void epicsThreadRealtimeLock(void) * Create and start a new thread */ epicsThreadId -epicsThreadCreate (const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) +epicsThreadCreateOpt ( + const char * name, + EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts ) { rtems_id tid; rtems_status_code sc; char c[4]; + unsigned stackSize; + + if(!opts) opts = &opts_default; + stackSize = opts->stackSize; if (!initialized) epicsThreadInit(); if (stackSize < RTEMS_MINIMUM_STACK_SIZE) { @@ -279,7 +290,7 @@ epicsThreadCreate (const char *name, } strncpy (c, name, sizeof c); sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]), - epicsThreadGetOssPriorityValue (priority), + epicsThreadGetOssPriorityValue (opts->priority), stackSize, RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), RTEMS_FLOATING_POINT|RTEMS_LOCAL, diff --git a/modules/libcom/src/osi/os/WIN32/osdThread.c b/modules/libcom/src/osi/os/WIN32/osdThread.c index 8cdb4a3f4..f78c7c0f4 100644 --- a/modules/libcom/src/osi/os/WIN32/osdThread.c +++ b/modules/libcom/src/osi/os/WIN32/osdThread.c @@ -464,6 +464,13 @@ epicsShareFunc unsigned int epicsShareAPI return stackSizeTable[stackSizeClass]; } +static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, STACK_SIZE(1)}; + +void epicsThreadOptsDefaults(epicsThreadOpts *opts) +{ + *opts = opts_default; +} + void epicsThreadCleanupWIN32 () { win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); @@ -579,8 +586,10 @@ static win32ThreadParam * epicsThreadImplicitCreate ( void ) /* * epicsThreadCreate () */ -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName, - unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC pFunc,void *pParm) +epicsThreadId epicsThreadCreateOpt ( + const char * pName, + EPICSTHREADFUNC pFunc, void * pParm, + const epicsThreadOpts *opts ) { win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); win32ThreadParam * pParmWIN32; @@ -592,18 +601,20 @@ epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName, return NULL; } + if(!opts) opts = &opts_default; + pParmWIN32 = epicsThreadParmCreate ( pName ); if ( pParmWIN32 == 0 ) { return ( epicsThreadId ) pParmWIN32; } pParmWIN32->funptr = pFunc; pParmWIN32->parm = pParm; - pParmWIN32->epicsPriority = priority; + pParmWIN32->epicsPriority = opts->priority; { unsigned threadId; pParmWIN32->handle = (HANDLE) _beginthreadex ( - 0, stackSize, epicsWin32ThreadEntry, + 0, opts->stackSize, epicsWin32ThreadEntry, pParmWIN32, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, & threadId ); @@ -615,7 +626,7 @@ epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName, pParmWIN32->id = ( DWORD ) threadId ; } - osdPriority = epicsThreadGetOsdPriorityValue (priority); + osdPriority = epicsThreadGetOsdPriorityValue (opts->priority); bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority ); if (!bstat) { CloseHandle ( pParmWIN32->handle ); diff --git a/modules/libcom/src/osi/os/posix/osdThread.c b/modules/libcom/src/osi/os/posix/osdThread.c index 755390eed..65e1929ec 100644 --- a/modules/libcom/src/osi/os/posix/osdThread.c +++ b/modules/libcom/src/osi/os/posix/osdThread.c @@ -430,15 +430,22 @@ void epicsThreadRealtimeLock(void) #endif } -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) -{ #if defined (OSITHREAD_USE_DEFAULT_STACK) - return 0; +#define STACK_SIZE(f) (0) #elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0 #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) static const unsigned stackSizeTable[epicsThreadStackBig+1] = { STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) }; +#else +#define STACK_SIZE(f) (0) +#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ + +epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) +{ +#if defined (OSITHREAD_USE_DEFAULT_STACK) + return 0; +#elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0 if (stackSizeClasspriority,opts->stackSize,funptr,parm); if(pthreadInfo==0) return 0; pthreadInfo->isEpicsThread = 1; setSchedulingPolicy(pthreadInfo,SCHED_FIFO); @@ -518,7 +535,7 @@ epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name, if(status==EPERM){ /* Try again without SCHED_FIFO*/ free_threadInfo(pthreadInfo); - pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); + pthreadInfo = init_threadInfo(name,opts->priority,opts->stackSize,funptr,parm); if(pthreadInfo==0) return 0; pthreadInfo->isEpicsThread = 1; status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, diff --git a/modules/libcom/src/osi/os/vxWorks/osdThread.c b/modules/libcom/src/osi/os/vxWorks/osdThread.c index ce01ea609..6a71301a2 100644 --- a/modules/libcom/src/osi/os/vxWorks/osdThread.c +++ b/modules/libcom/src/osi/os/vxWorks/osdThread.c @@ -133,6 +133,13 @@ unsigned int epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) return stackSizeTable[stackSizeClass]; } +static const epicsThreadOpts opts_default = {epicsThreadPriorityLow, 4000*ARCH_STACK_FACTOR}; + +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 @@ -190,19 +197,22 @@ static void createFunction(EPICSTHREADFUNC func, void *parm) #else #define TASK_FLAGS (VX_FP_TASK) #endif -epicsThreadId epicsThreadCreate(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) +epicsThreadId +epicsThreadCreateOpt ( + const char * name, + EPICSTHREADFUNC funptr, void * parm, const epicsThreadOpts *opts ) { int tid; + if(!opts) opts = &opts_default; + epicsThreadInit(); - if(stackSize<100) { - errlogPrintf("epicsThreadCreate %s illegal stackSize %d\n",name,stackSize); + if(opts->stackSize<100) { + errlogPrintf("epicsThreadCreate %s illegal stackSize %d\n",name,opts->stackSize); return(0); } - tid = taskSpawn((char *)name,getOssPriorityValue(priority), - TASK_FLAGS, stackSize, + tid = taskSpawn((char *)name,getOssPriorityValue(opts->priority), + TASK_FLAGS, opts->stackSize, (FUNCPTR)createFunction,(int)funptr,(int)parm, 0,0,0,0,0,0,0,0); if(tid==ERROR) {