static void callDone(dbCommon *precord, processNotify *ppn) { notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; epicsMutexUnlock(pnotifyGlobal->lock); if (ppn->requestType == processGetRequest || ppn->requestType == putProcessGetRequest) { ppn->getCallback(ppn, getFieldType); } dbScanUnlock(precord); ppn->doneCallback(ppn); epicsMutexMustLock(pnotifyGlobal->lock); if (pnotifyPvt->cancelWait && pnotifyPvt->userCallbackWait) { errlogPrintf("%s processNotify: both cancelWait and userCallbackWait true." "This is illegal\n", precord->name); pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; } if (!pnotifyPvt->cancelWait && !pnotifyPvt->userCallbackWait) { notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } if (pnotifyPvt->cancelWait) { pnotifyPvt->cancelWait = 0; epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } assert(pnotifyPvt->userCallbackWait); pnotifyPvt->userCallbackWait = 0; epicsEventSignal(pnotifyPvt->userCallbackEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; }
static void tester(void *raw) { caster_t *self = raw; epicsEventId sd; testDiag("UDP tester starts"); epicsMutexMustLock(lock); while(!self->shutdown) { epicsMutexUnlock(lock); epicsEventMustWait(cycled[1]); epicsMutexMustLock(lock); result = doCasterUDPPhase(self); cycles++; epicsEventSignal(cycled[0]); } testDiag("UDP tester stops"); sd = self->shutdownEvent; epicsMutexUnlock(lock); epicsEventSignal(sd); }
static void callUser(dbCommon *precord,putNotify *ppn) { putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); (*ppn->userCallback)(ppn); epicsMutexMustLock(pnotifyGlobal->lock); if(pputNotifyPvt->cancelWait && pputNotifyPvt->userCallbackWait) { errlogPrintf("%s putNotify: both cancelWait and userCallbackWait true." "This is illegal\n",precord->name); pputNotifyPvt->cancelWait = pputNotifyPvt->userCallbackWait = 0; } if(!pputNotifyPvt->cancelWait && !pputNotifyPvt->userCallbackWait) { putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } if(pputNotifyPvt->cancelWait) { pputNotifyPvt->cancelWait = 0; epicsEventSignal(pputNotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; } assert(pputNotifyPvt->userCallbackWait); pputNotifyPvt->userCallbackWait = 0; epicsEventSignal(pputNotifyPvt->userCallbackEvent); epicsMutexUnlock(pnotifyGlobal->lock); return; }
static void callbackTask(void *arg) { int prio = *(int*)arg; cbQueueSet *mySet = &callbackQueue[prio]; taskwdInsert(0, NULL, NULL); epicsEventSignal(startStopEvent); while(!mySet->shutdown) { void *ptr; if (epicsRingPointerIsEmpty(mySet->queue)) epicsEventMustWait(mySet->semWakeUp); while ((ptr = epicsRingPointerPop(mySet->queue))) { CALLBACK *pcallback = (CALLBACK *)ptr; if(!epicsRingPointerIsEmpty(mySet->queue)) epicsEventMustTrigger(mySet->semWakeUp); mySet->queueOverflow = FALSE; (*pcallback->callback)(pcallback); } } if(!epicsAtomicDecrIntT(&mySet->threadsRunning)) epicsEventSignal(startStopEvent); taskwdRemove(0); }
/** Called when asyn clients call pasynInt32->write(). * This function performs actions for some parameters, including ADAcquire, mar345Erase, etc. * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus mar345::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *functionName = "writeInt32"; status = setIntegerParam(function, value); if (function == ADAcquire) { if (value && (this->mode == mar345ModeIdle)) { /* Send an event to wake up the mar345 task. */ this->mode = mar345ModeAcquire; epicsEventSignal(this->startEventId); } if (!value && (this->mode != mar345ModeIdle)) { /* Stop acquiring (ends exposure, does not abort) */ epicsEventSignal(this->stopEventId); } } else if (function == mar345Erase) { if (value && (this->mode == mar345ModeIdle)) { this->mode = mar345ModeErase; /* Send an event to wake up the mar345 task. */ epicsEventSignal(this->startEventId); } } else if (function == mar345ChangeMode) { if (value && (this->mode == mar345ModeIdle)) { this->mode = mar345ModeChange; /* Send an event to wake up the mar345 task. */ epicsEventSignal(this->startEventId); } } else if (function == mar345Abort) { if (value && (this->mode != mar345ModeIdle)) { /* Abort operation */ setIntegerParam(ADStatus, mar345StatusAborting); epicsEventSignal(this->abortEventId); } } else { /* If this is not a parameter we have handled call the base class */ if (function < FIRST_MAR345_PARAM) status = ADDriver::writeInt32(pasynUser, value); } /* Do callbacks so higher layers see any changes */ callParamCallbacks(); if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); return status; }
/** Called when asyn clients call pasynInt32->write(). * This function performs actions for some parameters, including ADAcquire, ADTriggerMode, etc. * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus BISDetector::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; int adstatus; int maxSizeX; asynStatus status = asynSuccess; const char *functionName = "writeInt32"; status = setIntegerParam(function, value); if (function == ADAcquire) { getIntegerParam(ADStatus, &adstatus); if (value && (adstatus == ADStatusIdle)) { /* Send an event to wake up the BIS task. */ epicsEventSignal(this->startEventId); } if (!value && (adstatus != ADStatusIdle)) { /* This was a command to stop acquisition */ epicsEventSignal(this->stopEventId); } } else if (function == ADBinX) { getIntegerParam(ADMaxSizeX, &maxSizeX); if ((value == 1) || (value == 2) || (value == 4) || (value == 8)) { /* There is only 1 binning, set X and Y the same */ setIntegerParam(ADBinY, value); epicsSnprintf(this->toBIS, sizeof(this->toBIS), "[ChangeFrameSize /FrameSize=%d]", maxSizeX/value); writeBIS(BIS_DEFAULT_TIMEOUT); } else { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: invalid binning=%d, must be 1,2,4 or 8\n", driverName, functionName, value); status = asynError; } } else { /* If this parameter belongs to a base class call its method */ if (function < FIRST_BIS_PARAM) status = ADDriver::writeInt32(pasynUser, value); } /* Do callbacks so higher layers see any changes */ callParamCallbacks(); if (status) asynPrint(pasynUser, ASYN_TRACE_ERROR, "%s:%s: error, status=%d function=%d, value=%d\n", driverName, functionName, status, function, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, value=%d\n", driverName, functionName, function, value); return status; }
/* * Return whether the last get completed. In safe mode, as a * side effect, copy value from shared buffer to state set local buffer. */ epicsShareFunc boolean epicsShareAPI seq_pvGetComplete(SS_ID ss, VAR_ID varId) { epicsEventId getSem = ss->getSemId[varId]; SPROG *sp = ss->sprog; CHAN *ch = sp->chan + varId; pvStat status; if (!ch->dbch) { /* Anonymous PVs always complete immediately */ if (!(sp->options & OPT_SAFE)) errlogSevPrintf(errlogMajor, "pvGetComplete(%s): user error (variable not assigned)\n", ch->varName); return TRUE; } if (!ss->getReq[varId]) { errlogSevPrintf(errlogMinor, "pvGetComplete(%s): no pending get request for this variable\n", ch->varName); return TRUE; } switch (epicsEventTryWait(getSem)) { case epicsEventWaitOK: ss->getReq[varId] = NULL; epicsEventSignal(getSem); status = check_connected(ch->dbch, metaPtr(ch,ss)); /* TODO: returning either TRUE or FALSE here seems wrong. We return TRUE, so that state sets don't hang. Still means that user code has to check status by calling pvStatus and/or pvMessage. */ if (status) return TRUE; /* In safe mode, copy value and meta data from shared buffer to ss local buffer. */ if (sp->options & OPT_SAFE) /* Copy regardless of whether dirty flag is set or not */ ss_read_buffer(ss, ch, FALSE); return TRUE; case epicsEventWaitTimeout: return FALSE; case epicsEventWaitError: ss->getReq[varId] = NULL; epicsEventSignal(getSem); errlogSevPrintf(errlogFatal, "pvGetComplete: " "epicsEventTryWait(getSemId[%d]) failure\n", varId); default: /* pacify gcc which does not understand the we checked all possibilities */ return FALSE; } }
/* Starts "mcnt" jobs in a pool with initial and max * thread counts "icnt" and "mcnt". * The test ensures that all jobs run in parallel. * "cork" checks the function of pausing the run queue * with epicsThreadPoolQueueRun */ static void postjobs(size_t icnt, size_t mcnt, int cork) { size_t i; epicsThreadPool *pool; countPriv *priv=callocMustSucceed(1, sizeof(*priv), "postjobs priv alloc"); priv->guard=epicsMutexMustCreate(); priv->done=epicsEventMustCreate(epicsEventEmpty); priv->allrunning=epicsEventMustCreate(epicsEventEmpty); priv->count=mcnt; priv->job=callocMustSucceed(mcnt, sizeof(*priv->job), "postjobs job array"); testDiag("postjobs(%lu,%lu)", (unsigned long)icnt, (unsigned long)mcnt); { epicsThreadPoolConfig conf; epicsThreadPoolConfigDefaults(&conf); conf.initialThreads=icnt; conf.maxThreads=mcnt; testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); if(!pool) return; } if(cork) epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 0); for(i=0; i<mcnt; i++) { testDiag("i=%lu", (unsigned long)i); priv->job[i] = epicsJobCreate(pool, &countjob, priv); testOk1(priv->job[i]!=NULL); testOk1(epicsJobQueue(priv->job[i])==0); } if(cork) { /* no jobs should have run */ epicsMutexMustLock(priv->guard); testOk1(priv->count==mcnt); epicsMutexUnlock(priv->guard); epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 1); } testDiag("Waiting for all jobs to start"); epicsEventMustWait(priv->allrunning); testDiag("Stop all"); epicsEventSignal(priv->done); for(i=0; i<mcnt; i++) { testDiag("i=%lu", (unsigned long)i); epicsJobDestroy(priv->job[i]); } epicsThreadPoolDestroy(pool); epicsMutexDestroy(priv->guard); epicsEventDestroy(priv->allrunning); epicsEventDestroy(priv->done); free(priv->job); free(priv); }
/** Called when asyn clients call pasynInt32->write(). * This function sends a signal to the arrayGenTask thread if the value of P_RunStop has changed. * For all parameters it sets the value in the parameter library and calls any registered callbacks.. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus testArrayRingBuffer::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; asynStatus status = asynSuccess; const char *paramName; const char* functionName = "writeInt32"; /* Set the parameter in the parameter library. */ status = (asynStatus) setIntegerParam(function, value); /* Fetch the parameter string name for possible use in debugging */ getParamName(function, ¶mName); if (function == P_RunStop) { if (value) epicsEventSignal(eventId_); } else { /* All other parameters just get set in parameter list, no need to * act on them here */ } /* Do callbacks so higher layers see any changes */ status = (asynStatus) callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%d", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%d\n", driverName, functionName, function, paramName, value); return status; }
void scanShutdown(void) { int i; if (scanCtl == ctlExit) return; scanCtl = ctlExit; interruptAccept = FALSE; for (i = 0; i < nPeriodic; i++) { papPeriodic[i]->scanCtl = ctlExit; epicsEventSignal(papPeriodic[i]->loopEvent); epicsEventWait(startStopEvent); } scanOnce((dbCommon *)&exitOnce); epicsEventWait(startStopEvent); deletePeriodic(); ioscanDestroy(); epicsRingPointerDelete(onceQ); epicsEventDestroy(startStopEvent); epicsEventDestroy(onceSem); onceSem = startStopEvent = NULL; free(periodicTaskId); papPeriodic = NULL; periodicTaskId = NULL; }
void dbCaPause(void) { if (dbCaCtl == ctlRun) { dbCaCtl = ctlPause; epicsEventSignal(workListEvent); } }
static int motorAxisHome(AXIS_HDL pAxis, double min_velocity, double max_velocity, double acceleration, int forwards) { int status; char buff[100]; if (pAxis == NULL) return MOTOR_AXIS_ERROR; PRINT(pAxis->logParam, FLOW, "motorAxisHome: set card %d, axis %d to home\n", pAxis->card, pAxis->axis); sprintf(buff, "%dAC%.*f; %dVA%.*f;%dOR;", pAxis->axis+1, pAxis->maxDigits, acceleration * pAxis->stepSize, pAxis->axis+1, pAxis->maxDigits, max_velocity * pAxis->stepSize, pAxis->axis+1); status = sendOnly(pAxis->pController, buff); if (status) return(MOTOR_AXIS_ERROR); if (epicsMutexLock(pAxis->mutexId) == epicsMutexLockOK) { /* Insure that the motor record's next status update sees motorAxisDone = False. */ motorParam->setInteger(pAxis->params, motorAxisDone, 0); motorParam->callCallback(pAxis->params); epicsMutexUnlock(pAxis->mutexId); } /* Send a signal to the poller task which will make it do a poll, and switch to the moving poll rate */ epicsEventSignal(pAxis->pController->pollEventId); return MOTOR_AXIS_OK; }
static void addAction(caLink *pca, short link_action) { int callAdd; epicsMutexMustLock(workListLock); callAdd = (pca->link_action == 0); if (pca->link_action & CA_CLEAR_CHANNEL) { errlogPrintf("dbCa::addAction %d with CA_CLEAR_CHANNEL set\n", link_action); printLinks(pca); link_action = 0; } if (link_action & CA_CLEAR_CHANNEL) { if (++removesOutstanding >= removesOutstandingWarning) { errlogPrintf("dbCa::addAction pausing, %d channels to clear\n", removesOutstanding); printLinks(pca); } while (removesOutstanding >= removesOutstandingWarning) { epicsMutexUnlock(workListLock); epicsThreadSleep(1.0); epicsMutexMustLock(workListLock); } } pca->link_action |= link_action; if (callAdd) ellAdd(&workList, &pca->node); epicsMutexUnlock(workListLock); if (callAdd) epicsEventSignal(workListEvent); }
void omsMAXv::InterruptHandler( void * param ) { omsMAXv* pController = (omsMAXv*) param; volatile struct MAXv_motor *pmotor = (MAXv_motor*) pController->getCardAddress();; STATUS1 status1_flag; static char errmsg[65]; status1_flag.All = pmotor->status1_flag.All; /* Motion done handling */ if (status1_flag.Bits.done != 0) epicsEventSignal(pController->pollEventId_); if (status1_flag.Bits.cmndError) { strcpy(errmsg, "\nomsMAXv::InterruptHandler: command error - Port: "); strncat(errmsg, pController->getPortName(), sizeof(errmsg)-strlen(errmsg)-2); strcat(errmsg,"\n"); epicsInterruptContextMessage(errmsg); } /* unset this bit to not clear the text_response bit */ if (status1_flag.Bits.text_response != 0) status1_flag.Bits.text_response = 0; /* Release IRQ's. Clear bits by writing a 1 */ pmotor->status1_flag.All = status1_flag.All; /* do a dummy read to ensure that all previous writes, which may * have been queued in the VME bridge chip get processed */ status1_flag.All = pmotor->status1_flag.All; }
void func_EC1_ANT_SYS_RUN(void *pArg, double arg1, double arg2) { ST_STD_device* pSTDdev = (ST_STD_device *)pArg; if ( (int)arg1 ) { if( check_dev_run_condition(pSTDdev)== WR_ERROR) return; /* to do here */ epicsEventSignal( pSTDdev->ST_RTthread.threadEventId ); pSTDdev->StatusDev |= TASK_IN_PROGRESS; notify_error(ERR_SCN, "no error\n"); } else { if( check_dev_stop_condition(pSTDdev) == WR_ERROR) return; pSTDdev->StatusDev &= ~TASK_IN_PROGRESS; pSTDdev->StatusDev &= ~TASK_WAIT_FOR_TRIGGER; notify_error(ERR_SCN, "no error\n"); } }
/* Subscription handler callback. */ void CaObjectPrivate::subscriptionHandler( struct event_handler_args args ) { CaObject* context = contextFromCaUsr( args.usr, args.chid ); if( !context ) { return; } switch( args.status ) { case ECA_NORMAL : context->caPrivate->processChannel( args ); if( context->allowCallbacks ) { context->signalCallback( SUBSCRIPTION_SUCCESS ); } else { printf( "Late CA callback. CaObjectPrivate::subscriptionHandler() called during deletion of CaObject.\n" ); } break; default : if( context->allowCallbacks ) { context->signalCallback( SUBSCRIPTION_FAIL ); } else { printf( "Late CA callback. CaObjectPrivate::subscriptionHandler() called during deletion of CaObject.\n" ); } break; } epicsEventSignal( monitorEvent ); }
/* * logClientRestart () */ static void logClientRestart ( logClientId id ) { logClient *pClient = (logClient *)id; /* SMP safe state inspection */ epicsMutexMustLock ( pClient->mutex ); while ( ! pClient->shutdown ) { unsigned isConn; isConn = pClient->connected; epicsMutexUnlock ( pClient->mutex ); if ( isConn ) { logClientFlush ( pClient ); } else { logClientConnect ( pClient ); } epicsThreadSleep ( LOG_RESTART_DELAY ); epicsMutexMustLock ( pClient->mutex ); } epicsMutexUnlock ( pClient->mutex ); pClient->shutdownConfirm = 1u; epicsEventSignal ( pClient->stateChangeNotify ); }
static void notifyCallback(CALLBACK *pcallback) { processNotify *ppn = NULL; dbCommon *precord; notifyPvt *pnotifyPvt; callbackGetUser(ppn,pcallback); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; precord = dbChannelRecord(ppn->chan); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); assert(precord->ppnr); assert(pnotifyPvt->state == notifyRestartCallbackRequested || pnotifyPvt->state == notifyUserCallbackRequested); assert(ellCount(&pnotifyPvt->waitList) == 0); if (pnotifyPvt->cancelWait) { if (pnotifyPvt->state == notifyRestartCallbackRequested) { restartCheck(precord->ppnr); } epicsEventSignal(pnotifyPvt->cancelEvent); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } if(pnotifyPvt->state == notifyRestartCallbackRequested) { processNotifyCommon(ppn, precord); return; } /* All done. Clean up and call userCallback */ pnotifyPvt->state = notifyUserCallbackActive; assert(precord->ppn!=ppn); callDone(precord, ppn); }
int devIocStatsGetCpuUsage (loadInfo *pval) { if (cpuUsage.startSem) { if (cpuUsage.didNotComplete && cpuUsage.nBurnNow==0) { cpuUsage.usage = 100.0; } else { double temp; double ticksNow,nBurnNow; ticksNow = cpuUsage.tNow; nBurnNow = (double)cpuUsage.nBurnNow; ticksNow *= (double)cpuUsage.nBurnNoContention/nBurnNow; temp = ticksNow - cpuUsage.tNoContention; temp = 100.0 * temp/ticksNow; if(temp<0.0 || temp>100.0) temp=0.0;/*take care of tick overflow*/ cpuUsage.usage = temp; } cpuUsage.didNotComplete = TRUE; epicsEventSignal(cpuUsage.startSem); } else { cpuUsage.usage = 0.0; } pval->cpuLoad = cpuUsage.usage; return 0; }
static asynStatus float64Write(void *pvt,asynUser *pasynUser, epicsFloat64 value) { drvPvt *pdrvPvt = (drvPvt *)pvt; int addr; asynStatus status; ELLLIST *pclientList; interruptNode *pnode; asynFloat64Interrupt *pinterrupt; status = getAddr(pdrvPvt,pasynUser,&addr,0); if(status!=asynSuccess) return status; epicsMutexMustLock(pdrvPvt->lock); pdrvPvt->interruptDelay = value; epicsMutexUnlock(pdrvPvt->lock); epicsEventSignal(pdrvPvt->waitWork); asynPrint(pasynUser,ASYN_TRACEIO_DRIVER, "%s addr %d write %f\n",pdrvPvt->portName,addr,value); pasynManager->interruptStart(pdrvPvt->asynFloat64Pvt, &pclientList); pnode = (interruptNode *)ellFirst(pclientList); while (pnode) { pinterrupt = pnode->drvPvt; if(addr==pinterrupt->addr && pinterrupt->pasynUser->reason==1) { pinterrupt->callback(pinterrupt->userPvt,pinterrupt->pasynUser,value); break; } pnode = (interruptNode *)ellNext(&pnode->node); } pasynManager->interruptEnd(pdrvPvt->asynFloat64Pvt); return asynSuccess; }
void dbCaRun(void) { if (dbCaCtl == ctlPause) { dbCaCtl = ctlRun; epicsEventSignal(workListEvent); } }
/* This routine can be called from interrupt context */ int callbackRequest(CALLBACK *pcallback) { int priority; int pushOK; cbQueueSet *mySet; if (!pcallback) { epicsInterruptContextMessage("callbackRequest: pcallback was NULL\n"); return S_db_notInit; } priority = pcallback->priority; if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) { epicsInterruptContextMessage("callbackRequest: Bad priority\n"); return S_db_badChoice; } mySet = &callbackQueue[priority]; if (mySet->queueOverflow) return S_db_bufFull; pushOK = epicsRingPointerPush(mySet->queue, pcallback); if (!pushOK) { char msg[48] = "callbackRequest: "; strcat(msg, threadNamePrefix[priority]); strcat(msg, " ring buffer full\n"); epicsInterruptContextMessage(msg); mySet->queueOverflow = TRUE; return S_db_bufFull; } epicsEventSignal(mySet->semWakeUp); return 0; }
asynStatus asynNDArrayDriver::incrementQueuedArrayCount() { queuedArrayCountMutex_->lock(); queuedArrayCount_++; queuedArrayCountMutex_->unlock(); epicsEventSignal(queuedArrayEvent_); return asynSuccess; }
extern "C" void verifyTryLockThread ( void *pArg ) { struct verifyTryLock *pVerify = ( struct verifyTryLock * ) pArg; testOk1(epicsMutexTryLock(pVerify->mutex) == epicsMutexLockTimeout); epicsEventSignal ( pVerify->done ); }
static void msgbufSetSize(int size) { msgNode *pnextSend = pvtData.pnextSend; pnextSend->length = size+1; ellAdd(&pvtData.msgQueue, &pnextSend->node); epicsMutexUnlock(pvtData.msgQueueLock); epicsEventSignal(pvtData.waitForWork); }
static void timeoutCallback(asynUser *pasynUser) { cmdInfo *pcmdInfo = (cmdInfo *)pasynUser->userPvt; threadInfo *pthreadInfo = pcmdInfo->pthreadInfo; fprintf(pcmdInfo->file,"%s %s timeoutCallback\n",pthreadInfo->threadName,pcmdInfo->message); epicsThreadSleep(.04); epicsEventSignal(pcmdInfo->callbackDone); }
void put_event_handler ( struct event_handler_args args ) { /* Retrieve pv from event handler structure */ pv* pPv = args.usr; /* Store status, then give EPICS event */ pPv->status = args.status; epicsEventSignal( epId ); }
static void epicsThreadPoolControlImpl(epicsThreadPool *pool, epicsThreadPoolOption opt, unsigned int val) { if (pool->freezeopt) return; if (opt == epicsThreadPoolQueueAdd) { pool->pauseadd = !val; } else if (opt == epicsThreadPoolQueueRun) { if (!val && !pool->pauserun) pool->pauserun = 1; else if (val && pool->pauserun) { int jobs = ellCount(&pool->jobs); pool->pauserun = 0; if (jobs) { int wakeable = pool->threadsSleeping - pool->threadsWaking; /* first try to give jobs to sleeping workers */ if (wakeable) { int wakeup = jobs > wakeable ? wakeable : jobs; assert(wakeup > 0); jobs -= wakeup; pool->threadsWaking += wakeup; epicsEventSignal(pool->workerWakeup); CHECKCOUNT(pool); } } while (jobs-- && pool->threadsRunning < pool->conf.maxThreads) { if (createPoolThread(pool) == 0) { pool->threadsWaking++; epicsEventSignal(pool->workerWakeup); } else break; /* oops, couldn't create worker */ } CHECKCOUNT(pool); } } /* unknown options ignored */ }
static void blockCallback(asynUser *pasynUser) { cmdInfo *pcmdInfo = (cmdInfo *)pasynUser->userPvt; threadInfo *pthreadInfo = pcmdInfo->pthreadInfo; char *threadName = pthreadInfo->threadName; fprintf(pcmdInfo->file,"%s %s blockCallback\n",threadName,pcmdInfo->message); epicsEventSignal(pcmdInfo->callbackDone); epicsThreadSleep(.01); }
/* * Immediately terminate all state sets and jump to global exit block. */ epicsShareFunc void seq_exit(SS_ID ss) { PROG *sp = ss->prog; /* Ask all state set threads to exit */ sp->die = TRUE; /* Take care that we die even if waiting for initial connect */ epicsEventSignal(sp->ready); /* Wakeup all state sets unconditionally */ ss_wakeup(sp, 0); }