static void * start_routine(void *arg) { epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg; int status; int oldtype; sigset_t blockAllSig; sigfillset(&blockAllSig); pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL); status = pthread_setspecific(getpthreadInfo,arg); checkStatusQuit(status,"pthread_setspecific","start_routine"); status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype); checkStatusQuit(status,"pthread_setcanceltype","start_routine"); status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","start_routine"); ellAdd(&pthreadList,&pthreadInfo->node); pthreadInfo->isOnThreadList = 1; status = pthread_mutex_unlock(&listLock); checkStatusQuit(status,"pthread_mutex_unlock","start_routine"); (*pthreadInfo->createFunc)(pthreadInfo->createArg); epicsExitCallAtThreadExits (); free_threadInfo(pthreadInfo); return(0); }
/* * EPICS threads destroy themselves by returning from the thread entry function. * This simple wrapper provides the same semantics on RTEMS. */ static rtems_task threadWrapper (rtems_task_argument arg) { struct taskVar *v = (struct taskVar *)arg; (*v->funptr)(v->parm); epicsExitCallAtThreadExits (); taskVarLock (); if (v->back) v->back->forw = v->forw; else taskVarHead = v->forw; if (v->forw) v->forw->back = v->back; taskVarUnlock (); free (v->threadVariables); free (v->name); free (v); rtems_task_delete (RTEMS_SELF); }