added threadOnce() implementation for posix and vxworks

This commit is contained in:
William Lupton
2000-02-29 20:39:58 +00:00
parent a477054b92
commit 6cc7f656c6
6 changed files with 55 additions and 14 deletions

View File

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

View File

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

View File

@@ -1,5 +1,8 @@
#ifndef osdThreadh
#define osdThreadh
typedef int threadOnceId;
#define OSITHREAD_ONCE_INIT 0
#endif /* osdThreadh */

View File

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

View File

@@ -1,5 +1,8 @@
#ifndef osdThreadh
#define osdThreadh
typedef void *threadOnceId;
#define OSITHREAD_ONCE_INIT 0
#endif /* osdThreadh */

View File

@@ -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 <epicsAssert.h>