epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsigned int level) { epicsThreadOSD *pthreadInfo; int status; int found = 0; epicsThreadInit(); if(!showThread) { showThreadInfo(0,level); return; } status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll"); pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); while(pthreadInfo) { if (((epicsThreadId)pthreadInfo == showThread) || ((epicsThreadId)pthreadInfo->tid == showThread)) { found = 1; showThreadInfo(pthreadInfo,level); } pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); } status = pthread_mutex_unlock(&listLock); checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll"); if (!found) printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread); }
/* * Ensure func() is run only once. */ void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg) { #define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1 if (!initialized) epicsThreadInit(); epicsMutexMustLock(onceMutex); if (*id != EPICS_THREAD_ONCE_DONE) { if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ *id = epicsThreadGetIdSelf(); /* mark active */ epicsMutexUnlock(onceMutex); func(arg); epicsMutexMustLock(onceMutex); *id = EPICS_THREAD_ONCE_DONE; /* mark done */ } else if (*id == epicsThreadGetIdSelf()) { epicsMutexUnlock(onceMutex); cantProceed("Recursive epicsThreadOnce() initialization\n"); } else while (*id != EPICS_THREAD_ONCE_DONE) { /* Another thread is in the above func(arg) call. */ epicsMutexUnlock(onceMutex); epicsThreadSleep(epicsThreadSleepQuantum()); epicsMutexMustLock(onceMutex); } } epicsMutexUnlock(onceMutex); }
/* * Create and start a new thread */ epicsThreadId epicsThreadCreate (const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr,void *parm) { rtems_id tid; rtems_status_code sc; char c[4]; if (!initialized) epicsThreadInit(); if (stackSize < RTEMS_MINIMUM_STACK_SIZE) { errlogPrintf ("Warning: epicsThreadCreate %s illegal stackSize %d\n",name,stackSize); stackSize = RTEMS_MINIMUM_STACK_SIZE; } strncpy (c, name, sizeof c); sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]), epicsThreadGetOssPriorityValue (priority), stackSize, RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), RTEMS_FLOATING_POINT|RTEMS_LOCAL, &tid); if (sc != RTEMS_SUCCESSFUL) { errlogPrintf ("epicsThreadCreate create failure for %s: %s\n",name, rtems_status_text (sc)); return 0; } setThreadInfo (tid, name, funptr,parm); return (epicsThreadId)tid; }
epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf() { epicsThreadOSD *pthreadInfo; epicsThreadInit(); pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); if(pthreadInfo==NULL) pthreadInfo = createImplicit(); return(pthreadInfo->name); }
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) { epicsThreadOSD *pthreadInfo; epicsThreadInit(); pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); if(pthreadInfo==NULL) pthreadInfo = createImplicit(); assert ( pthreadInfo ); return(pthreadInfo); }
epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void) { pthread_key_t *key; int status; epicsThreadInit(); key = callocMustSucceed(1,sizeof(pthread_key_t),"epicsThreadPrivateCreate"); status = pthread_key_create(key,0); checkStatusQuit(status,"pthread_key_create","epicsThreadPrivateCreate"); return((epicsThreadPrivateId)key); }
epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void) { epicsThreadOSD *pthreadInfo; epicsThreadInit(); pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); if(pthreadInfo==NULL) pthreadInfo = createImplicit(); pthreadInfo->isSuspended = 1; epicsEventMustWait(pthreadInfo->suspendEvent); }
/* * Thread private storage implementation based on the vxWorks * implementation by Andrew Johnson APS/ASD. */ epicsThreadPrivateId epicsThreadPrivateCreate () { unsigned int taskVarIndex; static volatile unsigned int threadVariableCount = 0; if (!initialized) epicsThreadInit (); taskVarLock (); taskVarIndex = ++threadVariableCount; taskVarUnlock (); return (epicsThreadPrivateId)taskVarIndex; }
epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level) { epicsThreadOSD *pthreadInfo; int status; epicsThreadInit(); epicsThreadShow(0,level); status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","epicsThreadShowAll"); pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); while(pthreadInfo) { showThreadInfo(pthreadInfo,level); pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); } status = pthread_mutex_unlock(&listLock); checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadShowAll"); }
epicsShareFunc void epicsShareAPI epicsThreadExitMain(void) { epicsThreadOSD *pthreadInfo; epicsThreadInit(); pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); if(pthreadInfo==NULL) pthreadInfo = createImplicit(); if(pthreadInfo->createFunc) { errlogPrintf("called from non-main thread\n"); cantProceed("epicsThreadExitMain"); } else { free_threadInfo(pthreadInfo); pthread_exit(0); } }
epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) { static struct epicsThreadOSD threadOnceComplete; #define EPICS_THREAD_ONCE_DONE &threadOnceComplete int status; epicsThreadInit(); status = mutexLock(&onceLock); if(status) { fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n", strerror(status)); exit(-1); } if (*id != EPICS_THREAD_ONCE_DONE) { if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ *id = epicsThreadGetIdSelf(); /* mark active */ status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); func(arg); status = mutexLock(&onceLock); checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); *id = EPICS_THREAD_ONCE_DONE; /* mark done */ } else if (*id == epicsThreadGetIdSelf()) { status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); cantProceed("Recursive epicsThreadOnce() initialization\n"); } else while (*id != EPICS_THREAD_ONCE_DONE) { /* Another thread is in the above func(arg) call. */ status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); epicsThreadSleep(epicsThreadSleepQuantum()); status = mutexLock(&onceLock); checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); } } status = pthread_mutex_unlock(&onceLock); checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); }
epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr,void *parm) { epicsThreadOSD *pthreadInfo; int status; sigset_t blockAllSig, oldSig; epicsThreadInit(); assert(pcommonAttr); sigfillset(&blockAllSig); pthread_sigmask(SIG_SETMASK,&blockAllSig,&oldSig); pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); if(pthreadInfo==0) return 0; pthreadInfo->isEpicsThread = 1; setSchedulingPolicy(pthreadInfo,SCHED_FIFO); pthreadInfo->isFifoScheduled = 1; 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,priority,stackSize,funptr,parm); if(pthreadInfo==0) return 0; pthreadInfo->isEpicsThread = 1; status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, start_routine,pthreadInfo); } checkStatusOnce(status,"pthread_create"); if(status) { free_threadInfo(pthreadInfo); return 0; } status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL); checkStatusOnce(status,"pthread_sigmask"); return(pthreadInfo); }
epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void) { epicsThreadInit(); return(epicsThreadGetPriority(epicsThreadGetIdSelf())); }