From 34449f547aa6a6aa24fcce8a3b93b589d1d31883 Mon Sep 17 00:00:00 2001 From: William Lupton Date: Wed, 1 Mar 2000 02:30:20 +0000 Subject: [PATCH] new threadOnce implementation; added threadGetId --- src/libCom/osi/os/posix/osdThread.c | 41 ++++++++++++++++++++++----- src/libCom/osi/os/posix/osdThread.h | 4 --- src/libCom/osi/os/vxWorks/osdThread.c | 19 +++++++++---- src/libCom/osi/os/vxWorks/osdThread.h | 4 --- src/libCom/osi/osiThread.h | 23 +++++++++++---- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c index ff42f77be..1d0e3baab 100644 --- a/src/libCom/osi/os/posix/osdThread.c +++ b/src/libCom/osi/os/posix/osdThread.c @@ -175,7 +175,7 @@ static void once(void) semMutexGive(listMutex); } -void threadOnce(threadOnceId *id, void (*func)(void *), void *arg) +void threadOnceOsd(threadOnceId *id, void (*func)(void *), void *arg) { int status; @@ -183,15 +183,24 @@ void threadOnce(threadOnceId *id, void (*func)(void *), void *arg) checkStatusQuit(status,"pthread_once","threadOnce"); semMutexMustTake(onceMutex); - if(!(*id)) - { - *id = 1; + switch (id->state) { + case 0: + id->state = -1; + id->mutex = semMutexMustCreate(); + semMutexMustTake(id->mutex); semMutexGive(onceMutex); func(arg); - } - else - { + id->state = 1; + semMutexGive(id->mutex); + break; + case -1: semMutexGive(onceMutex); + semMutexMustTake(id->mutex); + semMutexGive(id->mutex); + break; + default: + semMutexGive(onceMutex); + break; } } @@ -350,6 +359,22 @@ threadId threadGetIdSelf(void) { return((threadId)pthreadInfo); } +threadId threadGetId(const char *name) { + threadInfo *pthreadInfo; + int status; + + status = pthread_once(&once_control,once); + checkStatusQuit(status,"pthread_once","threadGetId"); + + semMutexMustTake(listMutex); + for(pthreadInfo=(threadInfo *)ellFirst(&pthreadList); pthreadInfo; + pthreadInfo=(threadInfo *)ellNext((ELLNODE *)pthreadInfo)) { + if(strcmp(name,pthreadInfo->name) == 0) break; + } + semMutexGive(listMutex); + return((threadId)pthreadInfo); +} + const char *threadGetNameSelf() { threadInfo *pthreadInfo; @@ -378,6 +403,8 @@ void threadShow (void) int status; status = pthread_once(&once_control,once); + checkStatusQuit(status,"pthread_once","threadShow"); + errlogPrintf (" NAME ID PRI STATE WAIT\n"); semMutexMustTake(listMutex); for(pthreadInfo=(threadInfo *)ellFirst(&pthreadList); pthreadInfo; diff --git a/src/libCom/osi/os/posix/osdThread.h b/src/libCom/osi/os/posix/osdThread.h index 0d2e42388..ca61e704d 100644 --- a/src/libCom/osi/os/posix/osdThread.h +++ b/src/libCom/osi/os/posix/osdThread.h @@ -1,8 +1,4 @@ #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 5eaac7578..e35fc7846 100644 --- a/src/libCom/osi/os/vxWorks/osdThread.c +++ b/src/libCom/osi/os/vxWorks/osdThread.c @@ -73,9 +73,11 @@ epicsShareFunc unsigned int epicsShareAPI threadGetStackSize (threadStackSizeCla return stackSizeTable[stackSizeClass]; } -void threadOnce(threadOnceId *id, void (*func)(void *), void *arg) +void threadOnceOsd(threadOnceId *id, void (*func)(void *), void *arg) { - if(vxTas(id)) + /* not a good implementation (no guarantee that func() has finished before + the next task calls this routine); see the Posix implementation */ + if(vxTas(&id->state)) func(arg); } @@ -172,6 +174,12 @@ threadId threadGetIdSelf(void) return((threadId)taskIdSelf()); } +threadId threadGetId(const char *name) +{ + int tid = taskNameToId((char *)name); + return((threadId)(tid==ERROR?0:tid)); +} + const char *threadGetNameSelf (void) { return taskName(taskIdSelf()); @@ -197,7 +205,6 @@ void threadGetName (threadId id, char *name, size_t size) * The algorithm allows for threadPrivateCreate being called after * the first call to threadPrivateSet. */ - threadPrivateId threadPrivateCreate() { return((void *)++nthreadPrivate); @@ -210,9 +217,9 @@ void threadPrivateDelete(threadPrivateId id) } /* - *note that it is not necessary to have mutex for following - *because they must be called by the same thread -*/ + * Note that it is not necessary to have mutex for following + * because they must be called by the same thread + */ void threadPrivateSet (threadPrivateId id, void *pvt) { int indpthreadPrivate = (int)id; diff --git a/src/libCom/osi/os/vxWorks/osdThread.h b/src/libCom/osi/os/vxWorks/osdThread.h index b9606438e..ca61e704d 100644 --- a/src/libCom/osi/os/vxWorks/osdThread.h +++ b/src/libCom/osi/os/vxWorks/osdThread.h @@ -1,8 +1,4 @@ #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 808661cf2..11875e121 100644 --- a/src/libCom/osi/osiThread.h +++ b/src/libCom/osi/osiThread.h @@ -8,6 +8,7 @@ extern "C" { #include #include "shareLib.h" +#include "osiSem.h" typedef void (*THREADFUNC)(void *parm); @@ -32,8 +33,22 @@ typedef enum { epicsShareFunc unsigned int epicsShareAPI threadGetStackSize(threadStackSizeClass size); -/* threadOnceId is defined in osdThread.h; threadOnce() is defined after - osdThread.h has been included */ +/* threadOnce is a macro for efficiency (calls threadOnceOsd) */ +typedef struct { + int state; semMutexId mutex; +} threadOnceId; + +#define OSITHREAD_ONCE_INIT {0,0} + +epicsShareFunc void epicsShareAPI threadOnceOsd( + threadOnceId *id, void (*func)(void *), void *arg); + +#define threadOnce(id,func,arg) \ + do { \ + threadOnceId *idCopy =(id); \ + if((idCopy->state) <= 0) \ + threadOnceOsd(idCopy,func,arg); \ + } while(0) typedef void *threadId; epicsShareFunc threadId epicsShareAPI threadCreate(const char *name, @@ -49,6 +64,7 @@ epicsShareFunc int epicsShareAPI threadIsReady(threadId id); epicsShareFunc int epicsShareAPI threadIsSuspended(threadId id); epicsShareFunc void epicsShareAPI threadSleep(double seconds); epicsShareFunc threadId epicsShareAPI threadGetIdSelf(void); +epicsShareFunc threadId epicsShareAPI threadGetId(const char *name); epicsShareFunc const char * epicsShareAPI threadGetNameSelf(void); @@ -115,9 +131,6 @@ private: #include "osdThread.h" -epicsShareFunc void epicsShareAPI threadOnce( - threadOnceId *id, void (*func)(void *), void *arg); - #ifdef __cplusplus #include