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 dbProcessNotify(processNotify *ppn) { struct dbChannel *chan = ppn->chan; dbCommon *precord = dbChannelRecord(chan); short dbfType = dbChannelFieldType(chan); notifyPvt *pnotifyPvt; /* Must handle DBF_XXXLINKs as special case. * Only dbPutField will change link fields. * Also the record is not processed as a result */ ppn->status = notifyOK; ppn->wasProcessed = 0; if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { if (ppn->requestType == putProcessRequest || ppn->requestType == putProcessGetRequest) { /* Check if puts disabled */ if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) { ppn->putCallback(ppn, putDisabledType); } else { ppn->putCallback(ppn, putFieldType); } } if (ppn->requestType == processGetRequest || ppn->requestType == putProcessGetRequest) { ppn->getCallback(ppn, getFieldType); } ppn->doneCallback(ppn); return; } dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (pnotifyPvt && (pnotifyPvt->magic != MAGIC)) { printf("dbPutNotify:pnotifyPvt was not initialized\n"); pnotifyPvt = 0; } if (pnotifyPvt) { assert(pnotifyPvt->state == notifyUserCallbackActive); pnotifyPvt->userCallbackWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pnotifyPvt->userCallbackEvent); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); notifyCleanup(ppn); } pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; assert(!pnotifyPvt); notifyInit(ppn); pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (!precord->ppnr) { /* make sure record has a processNotifyRecord*/ precord->ppnr = dbCalloc(1, sizeof(processNotifyRecord)); precord->ppnr->precord = precord; ellInit(&precord->ppnr->restartList); } processNotifyCommon(ppn, precord); }
static asynStatus asynSetEos(const char *portName, int addr, enum eosType type, const char *eos) { asynUser *pasynUser; asynInterface *pasynInterface; eosArgs eosargs; if (eos == NULL) { printf("Missing EOS argument\n"); return asynError; } eosargs.eosLen = epicsStrnRawFromEscaped(eosargs.eos, sizeof eosargs.eos, eos, strlen(eos)); if (eosargs.eosLen >= sizeof eosargs.eos) { printf("End of string argument \"%s\" too long.\n", eos); return asynError; } if (findInterface(portName, addr, asynOctetType, setEos, &pasynUser, &pasynInterface) != asynSuccess) return asynError; pasynUser->timeout = 2; pasynUser->userPvt = &eosargs; pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED; eosargs.pasynOctet = (asynOctet *)pasynInterface->pinterface; eosargs. drvPvt = pasynInterface->drvPvt; eosargs.type = type; eosargs.done = epicsEventMustCreate(epicsEventEmpty); eosargs.status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, 0.0); if (eosargs.status == asynSuccess) epicsEventWait(eosargs.done); epicsEventDestroy(eosargs.done); if (eosargs.status != asynSuccess) printf("Set EOS failed: %s\n", pasynUser->errorMessage); pasynManager->freeAsynUser(pasynUser); return eosargs.status; }
epicsShareFunc int asynShowEos(const char *portName, int addr, enum eosType type) { asynInterface *pasynInterface; eosArgs eosargs; asynUser *pasynUser; if (findInterface(portName, addr, asynOctetType, getEos, &pasynUser, &pasynInterface) != asynSuccess) return asynError; pasynUser->timeout = 2; pasynUser->userPvt = &eosargs; pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED; eosargs.pasynOctet = (asynOctet *)pasynInterface->pinterface; eosargs. drvPvt = pasynInterface->drvPvt; eosargs.type = type; eosargs.done = epicsEventMustCreate(epicsEventEmpty); eosargs.status = pasynManager->queueRequest(pasynUser, asynQueuePriorityConnect, 0.0); if (eosargs.status == asynSuccess) epicsEventWait(eosargs.done); epicsEventDestroy(eosargs.done); if (eosargs.status != asynSuccess) printf("Set EOS failed: %s\n", pasynUser->errorMessage); pasynManager->freeAsynUser(pasynUser); if (eosargs.status == asynSuccess) { char cbuf[4*sizeof eosargs.eos + 2]; epicsStrnEscapedFromRaw(cbuf, sizeof cbuf, eosargs.eos, eosargs.eosLen); printf("\"%s\"\n", cbuf); } return eosargs.status; }
epicsShareFunc int asynSetOption(const char *portName, int addr, const char *key, const char *val) { asynUser *pasynUser; asynInterface *pasynInterface; setOptionArgs optionargs; if ((key == NULL) || (val == NULL)) { printf("Missing key/value argument\n"); return asynError; } if (findInterface(portName, addr, asynOptionType, setOption, &pasynUser, &pasynInterface) != asynSuccess) return asynError; pasynUser->timeout = 2; pasynUser->userPvt = &optionargs; pasynUser->reason = ASYN_REASON_QUEUE_EVEN_IF_NOT_CONNECTED; optionargs.pasynOption = (asynOption *)pasynInterface->pinterface; optionargs. drvPvt = pasynInterface->drvPvt; optionargs.key = key; optionargs.val = val; optionargs.done = epicsEventMustCreate(epicsEventEmpty); if (pasynManager->queueRequest(pasynUser,asynQueuePriorityConnect,0.0) != asynSuccess) { printf("queueRequest failed: %s\n", pasynUser->errorMessage); epicsEventDestroy(optionargs.done); pasynManager->freeAsynUser(pasynUser); return asynError; } epicsEventWait(optionargs.done); epicsEventDestroy(optionargs.done); pasynManager->freeAsynUser(pasynUser); return asynSuccess; }
void threadFunc_RTcore_DivideB(void *param) { ST_RTcore *pRTcore = (ST_RTcore*) param;; epicsThreadId pthreadInfo; #if USE_CPU_AFFINITY_RT pthreadInfo = epicsThreadGetIdSelf(); /* printf("%s: EPICS ID %p, pthreadID %lu\n", pthreadInfo->name, (void *)pthreadInfo, (unsigned long)pthreadInfo->tid); */ epicsThreadSetCPUAffinity( pthreadInfo, AFFINITY_RTCORE_DivB); epicsThreadSetPosixPriority(pthreadInfo, PRIOTY_RTCORE_DivB, "SCHED_FIFO"); #endif epicsThreadSleep(1.0); while(TRUE) { epicsEventWait( pRTcore->ST_DivThreadB.threadEventId); #if USE_RTCORE_DivB_HIGH WRITE32(pRTcore->base0 + 0x4, 0x1); #endif #if USE_RTCORE_DivB_LOW WRITE32(pRTcore->base0 + 0x4, 0x0); #endif } }
static void waitTimeout(niport *pniport,double seconds) { epicsEventWaitStatus status; transferState_t saveState; if(seconds<0.0) { status = epicsEventWait(pniport->waitForInterrupt); } else { status = epicsEventWaitWithTimeout(pniport->waitForInterrupt,seconds); } if(status==epicsEventWaitOK) return; saveState = pniport->transferState; pniport->transferState = transferStateIdle; switch(saveState) { case transferStateRead: pniport->status=asynTimeout; printStatus(pniport,"waitTimeout transferStateRead\n"); break; case transferStateWrite: pniport->status=asynTimeout; printStatus(pniport,"waitTimeout transferStateWrite\n"); break; case transferStateCmd: pniport->status=asynTimeout; printStatus(pniport,"waitTimeout transferStateCmd\n"); break; default: pniport->status=asynTimeout; printStatus(pniport,"waitTimeout transferState ?\n"); } }
void dbNotifyCancel(processNotify *ppn) { dbCommon *precord = dbChannelRecord(ppn->chan); notifyState state; notifyPvt *pnotifyPvt; dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); ppn->status = notifyCanceled; pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pnotifyPvt->state; switch (state) { case notifyUserCallbackRequested: case notifyRestartCallbackRequested: case notifyUserCallbackActive: /* Callback is scheduled or active, wait for it to complete */ pnotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pnotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; case notifyNotActive: break; case notifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case notifyRestartInProgress: case notifyProcessInProgress: { /*Take all records out of wait list */ processNotifyRecord *ppnrWait; while ((ppnrWait = (processNotifyRecord *) ellFirst(&pnotifyPvt->waitList))) { ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode); restartCheck(ppnrWait); } } if (precord->ppn == ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pnotifyPvt->state = notifyNotActive; notifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
/** Simulation task that runs as a separate thread. When the P_Run parameter is set to 1 * to rub the simulation it computes a 1 kHz sine wave with 1V amplitude and user-controllable * noise, and displays it on * a simulated scope. It computes waveforms for the X (time) and Y (volt) axes, and computes * statistics about the waveform. */ void testAsynPortDriver::simTask(void) { /* This thread computes the waveform and does callbacks with it */ double timePerDiv, voltsPerDiv, voltOffset, triggerDelay, noiseAmplitude; double updateTime, minValue, maxValue, meanValue; double time, timeStep; double noise, yScale; int run, i, maxPoints; double pi=4.0*atan(1.0); lock(); /* Loop forever */ while (1) { getDoubleParam(P_UpdateTime, &updateTime); getIntegerParam(P_Run, &run); // Release the lock while we wait for a command to start or wait for updateTime unlock(); if (run) epicsEventWaitWithTimeout(eventId_, updateTime); else (void) epicsEventWait(eventId_); // Take the lock again lock(); /* run could have changed while we were waiting */ getIntegerParam(P_Run, &run); if (!run) continue; getIntegerParam(P_MaxPoints, &maxPoints); getDoubleParam (P_TimePerDiv, &timePerDiv); getDoubleParam (P_VoltsPerDiv, &voltsPerDiv); getDoubleParam (P_VoltOffset, &voltOffset); getDoubleParam (P_TriggerDelay, &triggerDelay); getDoubleParam (P_NoiseAmplitude, &noiseAmplitude); time = triggerDelay; timeStep = timePerDiv * NUM_DIVISIONS / maxPoints; minValue = 1e6; maxValue = -1e6; meanValue = 0.; yScale = 1.0 / voltsPerDiv; for (i=0; i<maxPoints; i++) { noise = noiseAmplitude * (rand()/(double)RAND_MAX - 0.5); pData_[i] = AMPLITUDE * (sin(time*FREQUENCY*2*pi)) + noise; /* Compute statistics before doing the yOffset and yScale */ if (pData_[i] < minValue) minValue = pData_[i]; if (pData_[i] > maxValue) maxValue = pData_[i]; meanValue += pData_[i]; pData_[i] = NUM_DIVISIONS/2 + yScale * (voltOffset + pData_[i]); time += timeStep; } updateTimeStamp(); meanValue = meanValue/maxPoints; setDoubleParam(P_MinValue, minValue); setDoubleParam(P_MaxValue, maxValue); setDoubleParam(P_MeanValue, meanValue); callParamCallbacks(); doCallbacksFloat64Array(pData_, maxPoints, P_Waveform, 0); } }
void epicsShareAPI dbNotifyCancel(putNotify *ppn) { dbCommon *precord = ppn->paddr->precord; putNotifyState state; putNotifyPvt *pputNotifyPvt; assert(precord); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(!pputNotifyPvt || pputNotifyPvt->state==putNotifyNotActive) { epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } state = pputNotifyPvt->state; /*If callback is scheduled or active wait for it to complete*/ if(state==putNotifyUserCallbackRequested || state==putNotifyRestartCallbackRequested || state==putNotifyUserCallbackActive) { pputNotifyPvt->cancelWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pputNotifyPvt->cancelEvent); epicsMutexMustLock(pnotifyGlobal->lock); putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); return; } switch(state) { case putNotifyNotActive: break; case putNotifyWaitForRestart: assert(precord->ppn); assert(precord->ppn!=ppn); ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); break; case putNotifyRestartInProgress: case putNotifyPutInProgress: { /*Take all records out of wait list */ putNotifyRecord *ppnrWait; while((ppnrWait = (putNotifyRecord *)ellFirst(&pputNotifyPvt->waitList))){ ellSafeDelete(&pputNotifyPvt->waitList,&ppnrWait->waitNode); restartCheck(ppnrWait); } } if(precord->ppn==ppn) restartCheck(precord->ppnr); break; default: printf("dbNotify: illegal state for notifyCallback\n"); } pputNotifyPvt->state = putNotifyNotActive; putNotifyCleanup(ppn); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); }
asynNDArrayDriver::~asynNDArrayDriver() { queuedArrayUpdateRun_ = false; epicsEventSignal(queuedArrayEvent_); epicsEventWait(queuedArrayUpdateDone_); delete this->pNDArrayPoolPvt_; free(this->pArrays); delete this->pAttributeList; delete this->queuedArrayCountMutex_; }
void epicsShareAPI dbPutNotify(putNotify *ppn) { dbCommon *precord = ppn->paddr->precord; short dbfType = ppn->paddr->field_type; long status=0; putNotifyPvt *pputNotifyPvt; assert(precord); /*check for putField disabled*/ if(precord->disp) { if((void *)(&precord->disp) != ppn->paddr->pfield) { ppn->status = putNotifyPutDisabled; (*ppn->userCallback)(ppn); return; } } /* Must handle DBF_XXXLINKs as special case. * Only dbPutField will change link fields. * Also the record is not processed as a result */ if(dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { status=dbPutField(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest); ppn->status = (status==0) ? putNotifyOK : putNotifyError; (*ppn->userCallback)(ppn); return; } dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(pputNotifyPvt && (pputNotifyPvt->magic!=MAGIC)) { printf("dbPutNotify:pputNotifyPvt was not initialized\n"); pputNotifyPvt = 0; } if(pputNotifyPvt) { assert(pputNotifyPvt->state==putNotifyUserCallbackActive); pputNotifyPvt->userCallbackWait = 1; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); epicsEventWait(pputNotifyPvt->userCallbackEvent); dbScanLock(precord); epicsMutexMustLock(pnotifyGlobal->lock); putNotifyCleanup(ppn); } pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; assert(!pputNotifyPvt); putNotifyInit(ppn); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(!precord->ppnr) {/* make sure record has a putNotifyRecord*/ precord->ppnr = dbCalloc(1,sizeof(putNotifyRecord)); precord->ppnr->precord = precord; ellInit(&precord->ppnr->restartList); } putNotifyCommon(ppn,precord); }
static void initOnce(void) { if ((onceQ = epicsRingPointerCreate(onceQueueSize)) == NULL) { cantProceed("initOnce: Ring buffer create failed\n"); } onceSem = epicsEventMustCreate(epicsEventEmpty); onceTaskId = epicsThreadCreate("scanOnce", epicsThreadPriorityScanLow + nPeriodic, epicsThreadGetStackSize(epicsThreadStackBig), onceTask, 0); epicsEventWait(startStopEvent); }
static void twdShutdown(void *arg) { ELLNODE *cur; twdCtl = twdctlExit; epicsEventSignal(loopEvent); epicsEventWait(exitEvent); while ((cur = ellGet(&fList)) != NULL) { VALGRIND_MEMPOOL_FREE(&fList, cur); free(cur); } VALGRIND_DESTROY_MEMPOOL(&fList); }
static void tpnThread(void *pvt) { tpnInfo *ptpnInfo = (tpnInfo *)pvt; putNotify *ppn = (putNotify *)ptpnInfo->ppn; dbPutNotify(ppn); epicsEventWait(ptpnInfo->callbackDone); dbNotifyCancel(ppn); epicsEventDestroy(ptpnInfo->callbackDone); free((void *)ppn->paddr); free(ppn); free(ptpnInfo); }
static void tpnThread(void *pvt) { tpnInfo *ptpnInfo = (tpnInfo *) pvt; processNotify *ppn = (processNotify *) ptpnInfo->ppn; dbProcessNotify(ppn); epicsEventWait(ptpnInfo->callbackDone); dbNotifyCancel(ppn); epicsEventDestroy(ptpnInfo->callbackDone); dbChannelDelete(ppn->chan); free(ppn); free(ptpnInfo); }
static void spawnPeriodic(int ind) { periodic_scan_list *ppsl; char taskName[20]; ppsl = papPeriodic[ind]; sprintf(taskName, "scan-%g", ppsl->period); periodicTaskId[ind] = epicsThreadCreate( taskName, epicsThreadPriorityScanLow + ind, epicsThreadGetStackSize(epicsThreadStackBig), periodicTask, (void *)ppsl); epicsEventWait(startStopEvent); }
void asynNDArrayDriver::updateQueuedArrayCount() { while (queuedArrayUpdateRun_) { epicsEventWait(queuedArrayEvent_); // Exit early if (!queuedArrayUpdateRun_) break; lock(); setIntegerParam(NDNumQueuedArrays, getQueuedArrayCount()); callParamCallbacks(); unlock(); } epicsEventSignal(queuedArrayUpdateDone_); }
void callbackInit(void) { int i; int j; char threadName[32]; if (callbackIsInit) { errlogMessage("Warning: callbackInit called again before callbackCleanup\n"); return; } callbackIsInit = 1; if(!startStopEvent) startStopEvent = epicsEventMustCreate(epicsEventEmpty); cbCtl = ctlRun; timerQueue = epicsTimerQueueAllocate(0, epicsThreadPriorityScanHigh); for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { epicsThreadId tid; callbackQueue[i].semWakeUp = epicsEventMustCreate(epicsEventEmpty); callbackQueue[i].queue = epicsRingPointerLockedCreate(callbackQueueSize); if (callbackQueue[i].queue == 0) cantProceed("epicsRingPointerLockedCreate failed for %s\n", threadNamePrefix[i]); callbackQueue[i].queueOverflow = FALSE; if (callbackQueue[i].threadsConfigured == 0) callbackQueue[i].threadsConfigured = callbackThreadsDefault; for (j = 0; j < callbackQueue[i].threadsConfigured; j++) { if (callbackQueue[i].threadsConfigured > 1 ) sprintf(threadName, "%s-%d", threadNamePrefix[i], j); else strcpy(threadName, threadNamePrefix[i]); tid = epicsThreadCreate(threadName, threadPriority[i], epicsThreadGetStackSize(epicsThreadStackBig), (EPICSTHREADFUNC)callbackTask, &priorityValue[i]); if (tid == 0) { cantProceed("Failed to spawn callback thread %s\n", threadName); } else { epicsEventWait(startStopEvent); epicsAtomicIncrIntT(&callbackQueue[i].threadsRunning); } } } }
/* Caller must take devLock */ static void stopIsrThread(osdISR *isr) { if (isr->waiter_status==osdISRDone) return; isr->waiter_status = osdISRStopping; while (isr->waiter_status!=osdISRDone) { epicsMutexUnlock(isr->osd->devLock); epicsEventWait(isr->done); epicsMutexMustLock(isr->osd->devLock); } }
/** Array generation ask that runs as a separate thread. When the P_RunStop parameter is set to 1 * it periodically generates a burst of arrays. */ void testArrayRingBuffer::arrayGenTask(void) { double loopDelay; int runStop; int i, j; int burstLength; double burstDelay; int maxArrayLength; int arrayLength; lock(); /* Loop forever */ getIntegerParam(P_MaxArrayLength, &maxArrayLength); while (1) { getDoubleParam(P_LoopDelay, &loopDelay); getDoubleParam(P_BurstDelay, &burstDelay); getIntegerParam(P_RunStop, &runStop); // Release the lock while we wait for a command to start or wait for updateTime unlock(); if (runStop) epicsEventWaitWithTimeout(eventId_, loopDelay); else (void)epicsEventWait(eventId_); // Take the lock again lock(); /* runStop could have changed while we were waiting */ getIntegerParam(P_RunStop, &runStop); if (!runStop) continue; getIntegerParam(P_ArrayLength, &arrayLength); if (arrayLength > maxArrayLength) { arrayLength = maxArrayLength; setIntegerParam(P_ArrayLength, arrayLength); } getIntegerParam(P_BurstLength, &burstLength); for (i=0; i<burstLength; i++) { for (j=0; j<arrayLength; j++) { pData_[j] = i; } setIntegerParam(P_ScalarData, i); callParamCallbacks(); doCallbacksInt32Array(pData_, arrayLength, P_ArrayData, 0); if (burstDelay > 0.0) epicsThreadSleep(burstDelay); } } }
void verifyTryLock () { struct verifyTryLock verify; verify.mutex = epicsMutexMustCreate (); verify.done = epicsEventMustCreate ( epicsEventEmpty ); testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK); epicsThreadCreate ( "verifyTryLockThread", 40, epicsThreadGetStackSize(epicsThreadStackSmall), verifyTryLockThread, &verify ); testOk1(epicsEventWait ( verify.done ) == epicsEventWaitOK); epicsMutexUnlock ( verify.mutex ); epicsMutexDestroy ( verify.mutex ); epicsEventDestroy ( verify.done ); }
static void cpuUsageTask(void *parm) { while(TRUE) { int i; epicsTimeStamp tStart, tEnd; epicsEventWait(cpuUsage.startSem); cpuUsage.nBurnNow=0; epicsTimeGetCurrent(&tStart); for(i=0; i< cpuUsage.nBurnNoContention; i++) { cpuBurn(); epicsTimeGetCurrent(&tEnd); cpuUsage.tNow = epicsTimeDiffInSeconds(&tEnd, &tStart); ++cpuUsage.nBurnNow; } cpuUsage.didNotComplete = FALSE; } }
void FastCCD::dataStatsTask(void) { unsigned int status = 0; double timeout = 0.0; static const char *functionName = "dataStatsTask"; while(1) { //Read timeout for polling freq. this->lock(); timeout = dataStatsPollingPeriod; this->unlock(); if (timeout != 0.0) { status = epicsEventWaitWithTimeout(dataStatsEvent, timeout); } else { status = epicsEventWait(dataStatsEvent); } if (status == epicsEventWaitOK) { asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: Got status event\n", driverName, functionName); } cin_data_stats_t stats; cin_data_compute_stats(&stats); setIntegerParam(FastCCDDroppedPck, (int)stats.dropped_packets); setIntegerParam(FastCCDBadPck, (int)stats.mallformed_packets); setIntegerParam(FastCCDLastFrame, stats.last_frame); setIntegerParam(FastCCDPacketBuffer, stats.packet_used); setIntegerParam(FastCCDFrameBuffer, stats.frame_used); setIntegerParam(FastCCDImageBuffer, stats.image_used); //setDoubleParam(FastCCDDataRate, stats.datarate); this->lock(); callParamCallbacks(); this->unlock(); } }
void Scaler974::eventThread() { int done, presetCount; char response[100], statusString[20]; size_t responseLen, statusLen; int counts[MAX_CHANNELS]; int i; asynStatus status; static const char *functionName="eventThread"; while(1) { epicsEventWait(this->eventId); while(1) { status = this->sendCommand("SHOW_COUNTS", statusString, sizeof(statusString), &statusLen, response, sizeof(response), &responseLen); sscanf(response, "%d;%d;%d;%d;", &counts[0], &counts[1], &counts[2], &counts[3]); asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER, "%s:%s status=%d, counts=%d %d %d %d\n", driverName, functionName, status, counts[0], counts[1], counts[2], counts[3]); this->lock(); /* Get value of done in case scaler was stopped by scalerArm(0) */ getIntegerParam(scalerDone, &done); getIntegerParam(scalerPreset, &presetCount); if (!done && (counts[0] >= presetCount)) done = 1; setIntegerParam(scalerDone, done); for (i=0; i<MAX_CHANNELS; i++) { setIntegerParam(i, scalerReadSingle, counts[i]); callParamCallbacks(i, i); } this->unlock(); if (done) break; epicsThreadSleep(this->polltime); } } }
void drvQuadEM::callbackTask() { lock(); int numAcquire; int acquireMode; while (1) { unlock(); (void)epicsEventWait(ringEvent_); lock(); getIntegerParam(P_AcquireMode, &acquireMode); getIntegerParam(P_NumAcquire, &numAcquire); doDataCallbacks(); numAcquired_++; setIntegerParam(P_NumAcquired, numAcquired_); if ( (acquireMode == QEAcquireModeSingle) || ((acquireMode == QEAcquireModeMultiple) && (numAcquired_ >= numAcquire))) { setAcquire(0); setIntegerParam(P_Acquire, 0); } callParamCallbacks(); } }
void threadFunc_user_DAQ(void *param) { ST_STD_device *pSTDdev = (ST_STD_device*) param; /* ST_threadCfg *pDAQST_threadConfig ; */ if( !pSTDdev ) { printf("ERROR! threadFunc_user_DAQ() has null pointer of STD device.\n"); return; } while(TRUE) { /* sem_wait( &DAQsemaphore ); */ epicsEventWait( pSTDdev->ST_DAQThread.threadEventId); #if PRINT_DAQ_DEBUG printf(">>> %s: DAQthreadFunc() : Got epics Event and DAQ start\n", pSTDdev->taskName); #endif /* pSTDdev->StatusDev &= ~TASK_DAQ_STOPED; */ pSTDdev->StatusDev |= TASK_WAIT_FOR_TRIGGER; pSTDdev->StatusDev |= DEV_IN_LOOP_HTSTREAM; scanIoRequest(pSTDdev->ioScanPvt_status); // remove TG acq196_htstream(pSTDdev); } }
static void MM4000Poller(MM4000Controller *pController) { /* This is the task that polls the MM4000 */ double timeout; AXIS_HDL pAxis; int status; int itera, j; int axisDone; int offset; int anyMoving; int comStatus; int forcedFastPolls=0; char *p, *tokSave; char statusAllString[BUFFER_SIZE]; char positionAllString[BUFFER_SIZE]; char buff[BUFFER_SIZE]; timeout = pController->idlePollPeriod; epicsEventSignal(pController->pollEventId); /* Force on poll at startup */ while (1) { if (timeout != 0.) status = epicsEventWaitWithTimeout(pController->pollEventId, timeout); else status = epicsEventWait(pController->pollEventId); if (status == epicsEventWaitOK) { /* We got an event, rather than a timeout. This is because other software * knows that an axis should have changed state (started moving, etc.). * Force a minimum number of fast polls, because the controller status * might not have changed the first few polls */ forcedFastPolls = 10; } anyMoving = 0; /* Lock all the controller's axis. */ for (itera = 0; itera < pController->numAxes; itera++) { pAxis = &pController->pAxis[itera]; if (!pAxis->mutexId) break; epicsMutexLock(pAxis->mutexId); } comStatus = sendAndReceive(pController, "MS;", statusAllString, sizeof(statusAllString)); if (comStatus == 0) comStatus = sendAndReceive(pController, "TP;", positionAllString, sizeof(positionAllString)); for (itera=0; itera < pController->numAxes; itera++) { pAxis = &pController->pAxis[itera]; if (!pAxis->mutexId) break; if (comStatus != 0) { PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: error reading status=%d\n", comStatus); motorParam->setInteger(pAxis->params, motorAxisCommError, 1); } else { PARAMS params = pAxis->params; int intval, axisStatus; motorParam->setInteger(params, motorAxisCommError, 0); /* * Parse the status string * Status string format: 1MSx,2MSy,3MSz,... where x, y and z are the status * bytes for the motors */ offset = pAxis->axis*5 + 3; /* Offset in status string */ axisStatus = pAxis->axisStatus = statusAllString[offset]; if (axisStatus & MM4000_MOVING) { axisDone = 0; anyMoving = 1; } else axisDone = 1; motorParam->setInteger(params, motorAxisDone, axisDone); motorParam->setInteger(params, motorAxisHomeSignal, (axisStatus & MM4000_HOME)); motorParam->setInteger(params, motorAxisHighHardLimit, (axisStatus & MM4000_HIGH_LIMIT)); motorParam->setInteger(params, motorAxisLowHardLimit, (axisStatus & MM4000_LOW_LIMIT)); motorParam->setInteger(params, motorAxisDirection, (axisStatus & MM4000_DIRECTION)); motorParam->setInteger(params, motorAxisPowerOn, !(axisStatus & MM4000_POWER_OFF)); /* * Parse motor position * Position string format: 1TP5.012,2TP1.123,3TP-100.567,... * Skip to substring for this motor, convert to double */ strcpy(buff, positionAllString); tokSave = NULL; p = epicsStrtok_r(buff, ",", &tokSave); for (j=0; j < pAxis->axis; j++) p = epicsStrtok_r(NULL, ",", &tokSave); pAxis->currentPosition = atof(p+3); motorParam->setDouble(params, motorAxisPosition, (pAxis->currentPosition/pAxis->stepSize)); motorParam->setDouble(params, motorAxisEncoderPosn, (pAxis->currentPosition/pAxis->stepSize)); PRINT(pAxis->logParam, IODRIVER, "MM4000Poller: axis %d axisStatus=%x, position=%f\n", pAxis->axis, pAxis->axisStatus, pAxis->currentPosition); /* We would like a way to query the actual velocity, but this is not possible. If we could we could * set the direction, and Moving flags */ /* Check for controller error. */ comStatus = sendAndReceive(pController, "TE;", buff, sizeof(statusAllString)); if (buff[2] == '@') intval = 0; else { intval = 1; PRINT(pAxis->logParam, MOTOR_ERROR, "MM4000Poller: controller error %s\n", buff); } motorParam->setInteger(params, motorAxisProblem, intval); } motorParam->callCallback(pAxis->params); } /* Next axis */ /* UnLock all the controller's axis. */ for (itera = 0; itera < pController->numAxes; itera++) { pAxis = &pController->pAxis[itera]; if (!pAxis->mutexId) break; epicsMutexUnlock(pAxis->mutexId); } if (forcedFastPolls > 0) { timeout = pController->movingPollPeriod; forcedFastPolls--; } else if (anyMoving) timeout = pController->movingPollPeriod; else timeout = pController->idlePollPeriod; } /* End while */ }
/** This thread is woken up by an interrupt or a request to read status * It loops calling readFIFO until acquiring_ goes to false. * readFIFO only reads a limited amount of FIFO data at once in order * to avoid blocking the device support threads. */ void drvSIS3801::readFIFOThread() { int count; int signal; int chan; int nChans; int status; int i; bool acquiring; // We have a separate flag because we need to continue processing one last // time even if acquiring_ goes to false because acquisition was manually stopped epicsUInt32 scalerPresets[SIS38XX_MAX_SIGNALS]; epicsUInt32 *pOut=NULL; epicsTimeStamp t1, t2; static const char* functionName="readFIFOThread"; while(true) { epicsEventWait(readFIFOEventId_); // We got an event, which can come from acquisition starting, or FIFO full interrupt asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: got readFIFOEvent, eventType=%d, interrupt status=0x%8.8x\n", driverName, functionName, eventType_, registers_->csr_reg & 0xFFF00000); lock(); acquiring = acquiring_; unlock(); while (acquiring) { lock(); for (i=0; i<maxSignals_; i++) getIntegerParam(i, scalerPresets_, (int *)&scalerPresets[i]); getIntegerParam(mcaNumChannels_, &nChans); asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: scaler presets[0]=%d, scalerData[0]=%d\n", driverName, functionName, scalerPresets[0], scalerData_[0]); signal = nextSignal_; chan = nextChan_; count = 0; // This block of code can be slow and does not require the asynPortDriver lock because we are not // accessing object data that could change. // It does require the FIFO lock so no one resets the FIFO while it executes epicsMutexLock(fifoLockId_); unlock(); epicsTimeGetCurrent(&t1); /* Read out FIFO. It would be more efficient not to check the empty * flag on each transfer, using the almost empty flag. But this has gotten * too complex, and is unlikely to save time on new boards with lots of * memory. */ if (acquireMode_== ACQUIRE_MODE_MCS) { // Copy the data from the FIFO to the mcsBuffer pOut = mcsData_ + signal*maxChans_ + chan; asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: pOut=%p, signal=%d, chan=%d\n", driverName, functionName, pOut, signal, chan); while (((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0) && (chan < nChans) && acquiring_) { *pOut = registers_->fifo_reg; signal++; count++; if (signal >= maxSignals_) { signal = 0; chan++; pOut = mcsData_ + chan; } else { pOut += maxChans_; } } } else if (acquireMode_ == ACQUIRE_MODE_SCALER) { while ((registers_->csr_reg & STATUS_M_FIFO_FLAG_EMPTY)==0 && acquiring_) { scalerData_[signal] += registers_->fifo_reg; signal++; count++; if (signal >= maxSignals_) { for (i=0; i<maxSignals_; i++) { if ((scalerPresets[i] != 0) && (scalerData_[i] >= scalerPresets[i])) acquiring = false; } asynPrintIO(pasynUserSelf, ASYN_TRACEIO_DRIVER, (const char*)scalerData_, maxSignals_*sizeof(epicsUInt32), "%s:%s:\n", driverName, functionName); if (!acquiring) break; signal = 0; } } } epicsTimeGetCurrent(&t2); asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: read FIFO (%d) in %fs, acquiring=%d\n", driverName, functionName, count, epicsTimeDiffInSeconds(&t2, &t1), acquiring_); // Release the FIFO lock, we are done accessing the FIFO epicsMutexUnlock(fifoLockId_); // Take the lock since we are now changing object data lock(); nextChan_ = chan; nextSignal_ = signal; if (acquireMode_ == ACQUIRE_MODE_MCS) { asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: pOut=%p,signal=%d, chan=%d\n", driverName, functionName, pOut, signal, chan); checkMCSDone(); } else if (acquireMode_ == ACQUIRE_MODE_SCALER) { if (!acquiring) acquiring_ = false; if (!acquiring_) { asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: scaler done, doing callbacks\n", driverName, functionName); stopScaler(); setIntegerParam(scalerDone_, 1); callParamCallbacks(); } } /* Reenable interrupts in case we were woken up by an interrupt for FIFO almost full */ enableInterrupts(); acquiring = acquiring_; // Release the lock unlock(); // If we are still acquiring then sleep for a short time, but wake up if there is an interrupt if (acquiring) { status = epicsEventWaitWithTimeout(readFIFOEventId_, epicsThreadSleepQuantum()); if (status == epicsEventWaitOK) asynPrint(pasynUserSelf, ASYN_TRACE_FLOW, "%s:%s: got interrupt in epicsEventWaitWithTimeout, eventType=%d\n", driverName, functionName, eventType_); } } } }
/** Callback task that runs as a separate thread. */ void testErrors::callbackTask(void) { asynStatus currentStatus; int itemp; epicsInt32 iVal; epicsUInt32 uiVal; epicsFloat64 dVal; int i; char octetValue[20]; /* Loop forever */ while (1) { lock(); updateTimeStamp(); getIntegerParam(P_StatusReturn, &itemp); currentStatus = (asynStatus)itemp; getIntegerParam(P_Int32Value, &iVal); iVal++; if (iVal > 64) iVal=0; setIntegerParam(P_Int32Value, iVal); setParamStatus( P_Int32Value, currentStatus); getIntegerParam(P_BinaryInt32Value, &iVal); iVal++; if (iVal > 1) iVal=0; setIntegerParam(P_BinaryInt32Value, iVal); setParamStatus( P_BinaryInt32Value, currentStatus); getIntegerParam(P_MultibitInt32Value, &iVal); iVal++; if (iVal > MAX_INT32_ENUMS-1) iVal=0; setIntegerParam(P_MultibitInt32Value, iVal); setParamStatus( P_MultibitInt32Value, currentStatus); getUIntDigitalParam(P_UInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > 64) uiVal=0; setUIntDigitalParam(P_UInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_UInt32DigitalValue, currentStatus); getUIntDigitalParam(P_BinaryUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > 1) uiVal=0; setUIntDigitalParam(P_BinaryUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_BinaryUInt32DigitalValue, currentStatus); getUIntDigitalParam(P_MultibitUInt32DigitalValue, &uiVal, UINT32_DIGITAL_MASK); uiVal++; if (uiVal > MAX_UINT32_ENUMS-1) uiVal=0; setUIntDigitalParam(P_MultibitUInt32DigitalValue, uiVal, UINT32_DIGITAL_MASK); setParamStatus( P_MultibitUInt32DigitalValue, currentStatus); getDoubleParam(P_Float64Value, &dVal); dVal += 0.1; setDoubleParam(P_Float64Value, dVal); setParamStatus(P_Float64Value, currentStatus); sprintf(octetValue, "%.1f", dVal); setStringParam(P_OctetValue, octetValue); setParamStatus(P_OctetValue, currentStatus); for (i=0; i<MAX_ARRAY_POINTS; i++) { int8ArrayValue_[i] = iVal; int16ArrayValue_[i] = iVal; int32ArrayValue_[i] = iVal; float32ArrayValue_[i] = (epicsFloat32)dVal; float64ArrayValue_[i] = dVal; } callParamCallbacks(); setParamStatus(P_Int8ArrayValue, currentStatus); setParamStatus(P_Int16ArrayValue, currentStatus); setParamStatus(P_Int32ArrayValue, currentStatus); setParamStatus(P_Float32ArrayValue, currentStatus); setParamStatus(P_Float64ArrayValue, currentStatus); doCallbacksInt8Array(int8ArrayValue_, MAX_ARRAY_POINTS, P_Int8ArrayValue, 0); doCallbacksInt16Array(int16ArrayValue_, MAX_ARRAY_POINTS, P_Int16ArrayValue, 0); doCallbacksInt32Array(int32ArrayValue_, MAX_ARRAY_POINTS, P_Int32ArrayValue, 0); doCallbacksFloat32Array(float32ArrayValue_, MAX_ARRAY_POINTS, P_Float32ArrayValue, 0); doCallbacksFloat64Array(float64ArrayValue_, MAX_ARRAY_POINTS, P_Float64ArrayValue, 0); unlock(); epicsEventWait(eventId_); } }