From 6cc7f656c6aa15086ca54fe9f100c4bdb6cee59a Mon Sep 17 00:00:00 2001 From: William Lupton Date: Tue, 29 Feb 2000 20:39:58 +0000 Subject: [PATCH] added threadOnce() implementation for posix and vxworks --- src/libCom/osi/os/posix/osdSem.c | 4 +-- src/libCom/osi/os/posix/osdThread.c | 42 ++++++++++++++++++++------- src/libCom/osi/os/posix/osdThread.h | 5 +++- src/libCom/osi/os/vxWorks/osdThread.c | 8 +++++ src/libCom/osi/os/vxWorks/osdThread.h | 5 +++- src/libCom/osi/osiThread.h | 5 ++++ 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/libCom/osi/os/posix/osdSem.c b/src/libCom/osi/os/posix/osdSem.c index c7e0bdf1b..0873cf112 100644 --- a/src/libCom/osi/os/posix/osdSem.c +++ b/src/libCom/osi/os/posix/osdSem.c @@ -106,14 +106,14 @@ void semBinaryGive(semBinaryId id) int status; status = pthread_mutex_lock(&pbinary->mutex); - checkStatusQuit(status,"pthread_mutex_lock","semBinaryTake"); + checkStatusQuit(status,"pthread_mutex_lock","semBinaryGive"); if(!pbinary->isFull) { pbinary->isFull = 1; status = pthread_cond_signal(&pbinary->cond); checkStatus(status,"pthread_cond_signal"); } status = pthread_mutex_unlock(&pbinary->mutex); - checkStatusQuit(status,"pthread_mutex_unlock","semBinaryTake"); + checkStatusQuit(status,"pthread_mutex_unlock","semBinaryGive"); } semTakeStatus semBinaryTake(semBinaryId id) diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c index 4701f6bef..ff42f77be 100644 --- a/src/libCom/osi/os/posix/osdThread.c +++ b/src/libCom/osi/os/posix/osdThread.c @@ -50,7 +50,8 @@ typedef struct threadInfo { static pthread_once_t once_control = PTHREAD_ONCE_INIT; static pthread_key_t getpthreadInfo; -static semMutexId pthreadMutex; +static semMutexId onceMutex; +static semMutexId listMutex; static ELLLIST pthreadList; static commonAttr *pcommonAttr = 0; @@ -133,7 +134,8 @@ static void once(void) int status; pthread_key_create(&getpthreadInfo,0); - pthreadMutex = semMutexMustCreate(); + onceMutex = semMutexMustCreate(); + listMutex = semMutexMustCreate(); ellInit(&pthreadList); pcommonAttr = callocMustSucceed(1,sizeof(commonAttr),"osdThread::once"); status = pthread_attr_init(&pcommonAttr->attr); @@ -168,9 +170,29 @@ static void once(void) pthreadInfo = init_threadInfo("_main_",0,0,0,0); status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); checkStatusQuit(status,"pthread_setspecific","start_routine"); - semMutexMustTake(pthreadMutex); + semMutexMustTake(listMutex); ellAdd(&pthreadList,(ELLNODE *)pthreadInfo); - semMutexGive(pthreadMutex); + semMutexGive(listMutex); +} + +void threadOnce(threadOnceId *id, void (*func)(void *), void *arg) +{ + int status; + + status = pthread_once(&once_control,once); + checkStatusQuit(status,"pthread_once","threadOnce"); + + semMutexMustTake(onceMutex); + if(!(*id)) + { + *id = 1; + semMutexGive(onceMutex); + func(arg); + } + else + { + semMutexGive(onceMutex); + } } static void * start_routine(void *arg) @@ -180,15 +202,15 @@ static void * start_routine(void *arg) status = pthread_setspecific(getpthreadInfo,arg); checkStatusQuit(status,"pthread_setspecific","start_routine"); - semMutexMustTake(pthreadMutex); + semMutexMustTake(listMutex); ellAdd(&pthreadList,(ELLNODE *)pthreadInfo); - semMutexGive(pthreadMutex); + semMutexGive(listMutex); (*pthreadInfo->createFunc)(pthreadInfo->createArg); - semMutexMustTake(pthreadMutex); + semMutexMustTake(listMutex); ellDelete(&pthreadList,(ELLNODE *)pthreadInfo); - semMutexGive(pthreadMutex); + semMutexGive(listMutex); semBinaryDestroy(pthreadInfo->suspendSem); status = pthread_attr_destroy(&pthreadInfo->attr); @@ -357,13 +379,13 @@ void threadShow (void) status = pthread_once(&once_control,once); errlogPrintf (" NAME ID PRI STATE WAIT\n"); - semMutexMustTake(pthreadMutex); + semMutexMustTake(listMutex); for(pthreadInfo=(threadInfo *)ellFirst(&pthreadList); pthreadInfo; pthreadInfo=(threadInfo *)ellNext((ELLNODE *)pthreadInfo)) { errlogPrintf("%12.12s %8x %8d\n", pthreadInfo->name,(threadId) pthreadInfo,pthreadInfo->osiPriority); } - semMutexGive(pthreadMutex); + semMutexGive(listMutex); } threadPrivateId threadPrivateCreate(void) diff --git a/src/libCom/osi/os/posix/osdThread.h b/src/libCom/osi/os/posix/osdThread.h index 8587d6dbc..0d2e42388 100644 --- a/src/libCom/osi/os/posix/osdThread.h +++ b/src/libCom/osi/os/posix/osdThread.h @@ -1,5 +1,8 @@ - #ifndef osdThreadh #define osdThreadh +typedef int threadOnceId; + +#define OSITHREAD_ONCE_INIT 0 + #endif /* osdThreadh */ diff --git a/src/libCom/osi/os/vxWorks/osdThread.c b/src/libCom/osi/os/vxWorks/osdThread.c index 776fd75e2..5eaac7578 100644 --- a/src/libCom/osi/os/vxWorks/osdThread.c +++ b/src/libCom/osi/os/vxWorks/osdThread.c @@ -25,6 +25,8 @@ of this distribution. #include "cantProceed.h" #include "epicsAssert.h" +BOOL vxTas(void *address); + #if CPU_FAMILY == MC680X0 #define ARCH_STACK_FACTOR 1 #elif CPU_FAMILY == SPARC @@ -71,6 +73,12 @@ epicsShareFunc unsigned int epicsShareAPI threadGetStackSize (threadStackSizeCla return stackSizeTable[stackSizeClass]; } +void threadOnce(threadOnceId *id, void (*func)(void *), void *arg) +{ + if(vxTas(id)) + func(arg); +} + static void createFunction(THREADFUNC func, void *parm) { int tid = taskIdSelf(); diff --git a/src/libCom/osi/os/vxWorks/osdThread.h b/src/libCom/osi/os/vxWorks/osdThread.h index 8587d6dbc..b9606438e 100644 --- a/src/libCom/osi/os/vxWorks/osdThread.h +++ b/src/libCom/osi/os/vxWorks/osdThread.h @@ -1,5 +1,8 @@ - #ifndef osdThreadh #define osdThreadh +typedef void *threadOnceId; + +#define OSITHREAD_ONCE_INIT 0 + #endif /* osdThreadh */ diff --git a/src/libCom/osi/osiThread.h b/src/libCom/osi/osiThread.h index e74bf8a26..3dea87126 100644 --- a/src/libCom/osi/osiThread.h +++ b/src/libCom/osi/osiThread.h @@ -32,6 +32,9 @@ typedef enum { epicsShareFunc unsigned int epicsShareAPI threadGetStackSize(threadStackSizeClass size); +/* threadOnceId is defined in osdThread.h; threadOnce() is defined after + osdThread.h has been included */ + typedef void *threadId; epicsShareFunc threadId epicsShareAPI threadCreate(const char *name, unsigned int priority, unsigned int stackSize, @@ -110,6 +113,8 @@ private: #include "osdThread.h" +void threadOnce(threadOnceId *id, void (*func)(void *), void *arg); + #ifdef __cplusplus #include