void epicsShareAPI dbNotifyCompletion(dbCommon *precord) { putNotify *ppn = precord->ppn; putNotifyPvt *pputNotifyPvt; epicsMutexMustLock(pnotifyGlobal->lock); assert(ppn); assert(precord->ppnr); pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(pputNotifyPvt->state!=putNotifyRestartInProgress && pputNotifyPvt->state!=putNotifyPutInProgress) { epicsMutexUnlock(pnotifyGlobal->lock); return; } ellSafeDelete(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); if((ellCount(&pputNotifyPvt->waitList)!=0)) { restartCheck(precord->ppnr); } else if(pputNotifyPvt->state == putNotifyPutInProgress) { pputNotifyPvt->state = putNotifyUserCallbackRequested; restartCheck(precord->ppnr); callbackRequest(&pputNotifyPvt->callback); } else if(pputNotifyPvt->state == putNotifyRestartInProgress) { pputNotifyPvt->state = putNotifyRestartCallbackRequested; callbackRequest(&pputNotifyPvt->callback); } else { cantProceed("dbNotifyCompletion illegal state"); } epicsMutexUnlock(pnotifyGlobal->lock); }
void evgSoftSeq::abort(bool callBack) { if(!isLoaded() && !isEnabled()) return; // Prevent re-trigger m_seqRam->setRunMode(Single); m_seqRam->setTrigSrc(None); m_seqRam->reset(); m_isEnabled = false; if(mrmEVGSeqDebug) fprintf(stderr, "SS%u: Abort!\n",m_id); scanIoRequest(ioscanpvt); if(callBack) { /* * Satisfy any callback request pending on irqStop0 or irqStop1 * recList. As no 'End of sequence' Intrrupt will be generated. */ if(m_seqRam->getId() == 0) callbackRequest(&m_owner->irqStop0_cb); else callbackRequest(&m_owner->irqStop1_cb); } }
static long processLo(longoutRecord *pr) { devPvt *pPvt = (devPvt *)pr->dpvt; asynStatus status; if(pPvt->newOutputCallbackValue && getCallbackValue(pPvt)) { /* We got a callback from the driver */ if (pPvt->result.status == asynSuccess) { pr->val = pPvt->result.value & pPvt->mask; pr->udf = 0; } } else if(pr->pact == 0) { pPvt->result.value = pr->val & pPvt->mask; if(pPvt->canBlock) pr->pact = 1; status = pasynManager->queueRequest(pPvt->pasynUser, 0, 0); if((status==asynSuccess) && pPvt->canBlock) return 0; if(pPvt->canBlock) pr->pact = 0; reportQueueRequestStatus(pPvt, status); } pasynEpicsUtils->asynStatusToEpicsAlarm(pPvt->result.status, WRITE_ALARM, &pPvt->result.alarmStatus, INVALID_ALARM, &pPvt->result.alarmSeverity); recGblSetSevr(pr, pPvt->result.alarmStatus, pPvt->result.alarmSeverity); if (pPvt->numDeferredOutputCallbacks > 0) { callbackRequest(&pPvt->outputCallback); pPvt->numDeferredOutputCallbacks--; } pPvt->newOutputCallbackValue = 0; if(pPvt->result.status == asynSuccess) { return 0; } else { return -1; } }
/***************************************************************************** * * Find the next link-group that needs processing. * * If there are no link-groups left to process * call bdProcess() to complete the async record processing. * else * if the delay is > 0 seconds * schedule the watch dog task to wake us up later * else * invoke the watch-dog wakeup routine now * * * NOTE: * dbScanLock is already held for prec before this function is called. * ******************************************************************************/ static int processNextLink(seqRecord *prec) { callbackSeq *pcb = (callbackSeq *) (prec->dpvt); if (seqRecDebug > 5) printf("processNextLink(%s) looking for work to do, index = %d\n", prec->name, pcb->index); if (pcb->plinks[pcb->index] == NULL) { /* None left, finish up. */ (*(struct rset *)(prec->rset)).process(prec); } else { if (pcb->plinks[pcb->index]->dly > 0.0) { callbackRequestDelayed( &pcb->callback,pcb->plinks[pcb->index]->dly); } else { /* No delay, do it now. Avoid recursion by using the callback task */ callbackRequest(&pcb->callback); } } return(0); }
void bufRxManager::receive(epicsUInt8* raw,unsigned int usedlen) { /* CONTAINER doesn't work when the member is a pointer * because the GNU version's check isn't correct buffer *buf=CONTAINER(raw, buffer, data); */ buffer *buf=(buffer*)((char*)(raw) - offsetof(buffer, data)); if (usedlen>bsize()) throw std::out_of_range("User admitted overflowing Rx buffer"); buf->used=usedlen; if (usedlen==0) { // buffer returned w/o being used { SCOPED_LOCK(guard); ellAdd(&freebufs, &buf->node); } return; } { SCOPED_LOCK(guard); ellAdd(&usedbufs, &buf->node); } callbackRequest(&received_cb); }
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser, epicsFloat64 value) { devPvt *pPvt = (devPvt *)drvPvt; dbCommon *pr = pPvt->pr; ringBufferElement *rp; static const char *functionName="interruptCallbackOutput"; asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE, "%s %s::%s new value=%f\n", pr->name, driverName, functionName,value); if (!interruptAccept) return; epicsMutexLock(pPvt->devPvtLock); rp = &pPvt->ringBuffer[pPvt->ringHead]; rp->value = value; rp->time = pasynUser->timestamp; rp->status = pasynUser->auxStatus; rp->alarmStatus = pasynUser->alarmStatus; rp->alarmSeverity = pasynUser->alarmSeverity; pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1; if (pPvt->ringHead == pPvt->ringTail) { pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1; pPvt->ringBufferOverflows++; } else { /* If this callback was received during asynchronous record processing * we must defer calling callbackRequest until end of record processing */ if (pPvt->asyncProcessingActive) { pPvt->numDeferredOutputCallbacks++; } else { callbackRequest(&pPvt->outputCallback); } } epicsMutexUnlock(pPvt->devPvtLock); }
static void xycom566isr(void *arg) { xy566 *card=arg; epicsUInt16 csr; csr=READ16(card->base, XY566_CSR); if(!(csr&XY566_CSR_PND)) return; /* not ours */ if(card->use_seq_clk) WRITE8(card->base, XY566_STC, 0xC2); /* Disarm Seq. trig clock */ /* Disable sequence controller, acknowledge * interrupts, and schedule further processing * out of interrupt context */ csr&=~XY566_CSR_SEQ; /* disable seq. cont. */ /* writing back what was read will clear any pending * interrupts */ WRITE16(card->base, XY566_CSR, csr); callbackRequest(&card->cb_irq); return; }
/************************************************** * scalerISR() ***************************************************/ STATIC void scalerISR(int card) { volatile char *addr; uint16 value; Debug(5, "%s", "scalerISR: entry\n"); if ((card+1) > scaler_total_cards) return; addr = scaler_state[card]->localAddr; /* disable interrupts during processing */ value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) & 0x7f; writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value); /* clear interrupt */ writeReg16(addr,IRQ_RESET_OFFSET, 0); /* tell record support the hardware is done counting */ scaler_state[card]->done = 1; /* get the record processed */ callbackRequest(scaler_state[card]->pcallback); /* enable interrupts */ value = readReg16(addr, IRQ_LEVEL_ENABLE_OFFSET) | 0x80; writeReg16(addr, IRQ_LEVEL_ENABLE_OFFSET, value); return; }
void evgMrm::isr(void* arg) { evgMrm *evg = (evgMrm*)(arg); epicsUInt32 flags = READ32(evg->m_pReg, IrqFlag); epicsUInt32 enable = READ32(evg->m_pReg, IrqEnable); epicsUInt32 active = flags & enable; if(!active) return; if(active & EVG_IRQ_STOP_RAM(0)) { if(evg->irqStop0_queued==0) { callbackRequest(&evg->irqStop0_cb); evg->irqStop0_queued=1; } else if(evg->irqStop0_queued==1) { WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_STOP_RAM(0)); evg->irqStop0_queued=2; } } if(active & EVG_IRQ_STOP_RAM(1)) { if(evg->irqStop1_queued==0) { callbackRequest(&evg->irqStop1_cb); evg->irqStop1_queued=1; } else if(evg->irqStop1_queued==1) { WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_STOP_RAM(1)); evg->irqStop1_queued=2; } } if(active & EVG_IRQ_EXT_INP) { if(evg->irqExtInp_queued==0) { callbackRequest(&evg->irqExtInp_cb); evg->irqExtInp_queued=1; } else if(evg->irqExtInp_queued==1) { WRITE32(evg->getRegAddr(), IrqEnable, enable & ~EVG_IRQ_EXT_INP); evg->irqExtInp_queued=2; } } WRITE32(evg->m_pReg, IrqFlag, flags); // Clear the interrupt causes READ32(evg->m_pReg, IrqFlag); // Make sure the clear completes before returning return; }
/*CODE that interacts with drvAb*/ LOCAL void drvCallback(void *drvPvt) { ab1771IXRecord *precord; recordPvt *precordPvt; /*run myCallback under general purpose callback task*/ precord = (*pabDrv->getUserPvt)(drvPvt); precordPvt = precord->dpvt; callbackSetPriority(precord->prio,&precordPvt->callback); callbackRequest(&precordPvt->callback); }
void postEvent(event_list *pel) { int prio; if (scanCtl != ctlRun) return; if (!pel) return; for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { if (ellCount(&pel->scan_list[prio].list) >0) callbackRequest(&pel->callback[prio]); } }
static void asInitTask(ASDBCALLBACK *pcallback) { long status; taskwdInsert(epicsThreadGetIdSelf(), wdCallback, (void *)pcallback); status = asInitCommon(); taskwdRemove(epicsThreadGetIdSelf()); asInitTheadId = 0; if(pcallback) { pcallback->status = status; callbackRequest(&pcallback->callback); } }
/************************************************** * scalerISR() ***************************************************/ STATIC void scalerISR() { Debug(5, "%s", "scalerISR: entry\n"); int card = 0; /* tell record support the hardware is done counting */ scaler_state[card]->done = 1; /* get the record processed */ callbackRequest(scaler_state[card]->pcallback); return; }
/* Callback routine gets called when acquisition completes */ static void interruptCallback(void *drvPvt, asynUser *pasynUser, epicsInt32 value) { scalerAsynPvt *pPvt = (scalerAsynPvt *)drvPvt; scalerRecord *psr = pPvt->psr; /* Ignore callbacks when done value is 0 */ if (value == 0) return; pPvt->done = 1; asynPrint(pPvt->pasynUser[0], ASYN_TRACEIO_DEVICE, "%s devScalerAsyn::interruptCallback new value=%d\n", psr->name, value); callbackRequest(pPvt->pcallback); }
static long processAo(aoRecord *pr) { devPvt *pPvt = (devPvt *)pr->dpvt; asynStatus status; epicsMutexLock(pPvt->devPvtLock); if (pPvt->newOutputCallbackValue && getCallbackValue(pPvt)) { if (pPvt->result.status == asynSuccess) { epicsFloat64 val64 = pPvt->result.value; /* ASLO/AOFF conversion */ if (pr->aslo != 0.0) val64 *= pr->aslo; val64 += pr->aoff; pr->val = val64; pr->udf = 0; } } else if(pr->pact == 0) { /* ASLO/AOFF conversion */ epicsFloat64 val64 = pr->oval - pr->aoff; if (pr->aslo != 0.0) val64 /= pr->aslo; pPvt->result.value = val64; if(pPvt->canBlock) { pr->pact = 1; pPvt->asyncProcessingActive = 1; } epicsMutexUnlock(pPvt->devPvtLock); status = pasynManager->queueRequest(pPvt->pasynUser, 0, 0); if((status==asynSuccess) && pPvt->canBlock) return 0; if(pPvt->canBlock) pr->pact = 0; epicsMutexLock(pPvt->devPvtLock); reportQueueRequestStatus(pPvt, status); } pasynEpicsUtils->asynStatusToEpicsAlarm(pPvt->result.status, WRITE_ALARM, &pPvt->result.alarmStatus, INVALID_ALARM, &pPvt->result.alarmSeverity); recGblSetSevr(pr, pPvt->result.alarmStatus, pPvt->result.alarmSeverity); if (pPvt->numDeferredOutputCallbacks > 0) { callbackRequest(&pPvt->outputCallback); pPvt->numDeferredOutputCallbacks--; } pPvt->newOutputCallbackValue = 0; pPvt->asyncProcessingActive = 0; epicsMutexUnlock(pPvt->devPvtLock); if(pPvt->result.status == asynSuccess) { return 0; } else { pPvt->result.status = asynSuccess; return -1; } }
static void ntpshmhooks(initHookState state) { if(state!=initHookAfterIocRunning) return; epicsThreadOnce(&ntponce, &ntpshminit, 0); epicsMutexMustLock(ntpShm.ntplock); if(ntpShm.evr) { callbackRequest(&ntpShm.ntpcb); fprintf(stderr, "Starting NTP SHM writer for segment %d\n", ntpShm.segid); } epicsMutexUnlock(ntpShm.ntplock); }
/************************************************** * scalerEndOfGateISR() ***************************************************/ STATIC void scalerEndOfGateISR(int card) { #ifdef vxWorks Debug(5, "%s", "scalerEndOfGateISR: entry\n"); #endif if (card >= scalerVS_total_cards) { return; } else { /* tell record support the hardware is done counting */ scalerVS_state[card]->done = 1; /* get the record processed */ callbackRequest(scalerVS_state[card]->pcallback); } }
/* Return a bit mask indicating each priority level * in which a callback request was successfully queued. */ unsigned int scanIoRequest(IOSCANPVT piosh) { int prio; unsigned int queued = 0; if (scanCtl != ctlRun) return 0; for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { io_scan_list *piosl = &piosh->iosl[prio]; if (ellCount(&piosl->scan_list.list) > 0) if (!callbackRequest(&piosl->callback)) queued |= 1 << prio; } return queued; }
static void restartCheck(processNotifyRecord *ppnr) { dbCommon *precord = ppnr->precord; processNotify *pfirst; notifyPvt *pnotifyPvt; assert(precord->ppn); pfirst = (processNotify *) ellFirst(&ppnr->restartList); if (!pfirst) { precord->ppn = 0; return; } pnotifyPvt = (notifyPvt *) pfirst->pnotifyPvt; assert(pnotifyPvt->state == notifyWaitForRestart); /* remove pfirst from restartList */ ellSafeDelete(&ppnr->restartList, &pfirst->restartNode); /*make pfirst owner of the record*/ precord->ppn = pfirst; /* request callback for pfirst */ pnotifyPvt->state = notifyRestartCallbackRequested; callbackRequest(&pnotifyPvt->callback); }
static void notify(void *pPrivate) { CALLBACK *pcallback = (CALLBACK *)pPrivate; callbackRequest(pcallback); }
int callbackRequestProcessCallback(CALLBACK *pcallback, int Priority, void *pRec) { callbackSetProcess(pcallback, Priority, pRec); return callbackRequest(pcallback); }
static void wdCallback(void *arg) { ASDBCALLBACK *pcallback = (ASDBCALLBACK *)arg; pcallback->status = S_asLib_InitFailed; callbackRequest(&pcallback->callback); }
void ni1014(void *pvt) { niport *pniport = (niport *)pvt; transferState_t state = pniport->transferState; epicsUInt8 isr1,isr2,octet; char message[80]; pniport->isr2 = isr2 = readRegister(pniport,ISR2); pniport->isr1 = isr1 = readRegister(pniport,ISR1); writeRegister(pniport,CSR1,2); /*acknowledge interrupt*/ if(isr2&SRQI) callbackRequest(&pniport->callback); if(isr1&ERR) { if(state!=transferStateIdle) { sprintf(pniport->errorMessage,"\n%s interruptHandler ERR state %d\n", pniport->portName,state); pniport->status = asynError; epicsEventSignal(pniport->waitForInterrupt); } goto exit; } switch(state) { case transferStateCmd: if(!isr2&CO) goto exit; if(pniport->bytesRemainingCmd == 0) { pniport->transferState = pniport->nextTransferState; if(pniport->transferState==transferStateIdle) { epicsEventSignal(pniport->waitForInterrupt); } else { writeRegister(pniport,AUXMR,AUXGTS); } break ; } octet = *pniport->nextByteCmd; writeRegister(pniport,CDOR,(epicsUInt8)octet); --(pniport->bytesRemainingCmd); ++(pniport->nextByteCmd); break; case transferStateWrite: if(!isr1&DO) goto exit; if(pniport->bytesRemainingWrite == 0) { pniport->transferState = transferStateIdle; writeRegister(pniport,AUXMR,AUXTCA); epicsEventSignal(pniport->waitForInterrupt); break ; } if(pniport->bytesRemainingWrite==1) writeRegister(pniport,AUXMR,AUXEOI); octet = *pniport->nextByteWrite; writeRegister(pniport,CDOR,(epicsUInt8)octet); --(pniport->bytesRemainingWrite); ++(pniport->nextByteWrite); break; case transferStateRead: if(!isr1&DI) break; octet = readRegister(pniport,DIR); *pniport->nextByteRead = octet; --(pniport->bytesRemainingRead); ++(pniport->nextByteRead); if((pniport->eos != -1 ) && (octet == pniport->eos)) pniport->eomReason |= ASYN_EOM_EOS; if(ENDRX&isr1) pniport->eomReason |= ASYN_EOM_END; if(pniport->bytesRemainingRead == 0) pniport->eomReason |= ASYN_EOM_CNT; if(pniport->eomReason) { pniport->transferState = transferStateIdle; writeRegister(pniport,AUXMR,AUXTCS); epicsEventSignal(pniport->waitForInterrupt); break; } writeRegister(pniport,AUXMR,AUXFH); break; case transferStateIdle: if(!isr1&DI) goto exit; octet = readRegister(pniport,DIR); sprintf(message,"%s ni1014IH transferStateIdle received %2.2x\n", pniport->portName,octet); epicsInterruptContextMessage(message); } exit: /* Force synchronization of VMEbus writes on PPC CPU boards. */ readRegister(pniport,ADSR); }