long epicsShareAPI dbtr(const char *pname) { DBADDR addr; long status; struct dbCommon *precord; if (!pname || !*pname) { printf("Usage: dbtr \"pv name\"\n"); return 1; } if (nameToAddr(pname, &addr)) return -1; precord = (struct dbCommon*)addr.precord; if (precord->pact) { printf("record active\n"); return 1; } dbScanLock(precord); status = dbProcess(precord); dbScanUnlock(precord); if (status) recGblRecordError(status, precord, "dbtr(dbProcess)"); dbpr(pname, 3); return 0; }
void DbPvPut::put(PVStructurePtr const &pvStructure, BitSetPtr const & bitSet) { if (DbPvDebug::getLevel() > 0) printf("dbPvPut::put()\n"); this->pvStructure = pvStructure; this->bitSet = bitSet; if (block && process) { dbProcessNotify(pNotify.get()); return; } Lock lock(dataMutex); PVFieldPtr pvField = pvStructure.get()->getPVFields()[0]; if (propertyMask & dbUtil->dbPutBit) { status = dbUtil->putField( channelPutRequester, propertyMask, dbPv->getDbChannel(), pvField); } else { dbScanLock(dbChannelRecord(dbPv->getDbChannel())); status = dbUtil->put( channelPutRequester, propertyMask, dbPv->getDbChannel(), pvField); if (process) dbProcess(dbChannelRecord(dbPv->getDbChannel())); dbScanUnlock(dbChannelRecord(dbPv->getDbChannel())); } lock.unlock(); channelPutRequester->putDone(status, getPtrSelf()); }
void DbPvPut::put(PVStructurePtr const &pvStructure, BitSetPtr const & bitSet) { if(DbPvDebug::getLevel()>0) printf("dbPvPut::put()\n"); Lock lock(dataMutex); this->pvStructure = pvStructure; this->bitSet = bitSet; PVFieldPtr pvField = pvStructure.get()->getPVFields()[0]; if(propertyMask&dbUtil->dbPutBit) { Status status = dbUtil->putField( channelPutRequester,propertyMask,dbAddr,pvField); lock.unlock(); channelPutRequester->putDone(status,getPtrSelf()); return; } dbScanLock(dbAddr.precord); Status status = dbUtil->put( channelPutRequester, propertyMask, dbAddr, pvField); if (process && !block) dbProcess(dbAddr.precord); dbScanUnlock(dbAddr.precord); lock.unlock(); if (block && process) { epicsUInt8 value = 1; pNotify.get()->pbuffer = &value; dbPutNotify(pNotify.get()); } else { channelPutRequester->putDone(status, getPtrSelf()); } }
static void outputCallbackCallback(CALLBACK *pcb) { devPvt *pPvt; static const char *functionName="outputCallbackCallback"; callbackGetUser(pPvt, pcb); { dbCommon *pr = pPvt->pr; dbScanLock(pr); epicsMutexLock(pPvt->devPvtLock); pPvt->newOutputCallbackValue = 1; dbProcess(pr); if (pPvt->newOutputCallbackValue != 0) { /* We called dbProcess but the record did not process, perhaps because PACT was 1 * Need to remove ring buffer element */ asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s %s::%s warning dbProcess did not process record, PACT=%d\n", pr->name, driverName, functionName,pr->pact); getCallbackValue(pPvt); pPvt->newOutputCallbackValue = 0; } epicsMutexUnlock(pPvt->devPvtLock); dbScanUnlock(pr); } }
static void scanList(scan_list *psl) { /* When reading this code remember that the call to dbProcess can result * in the SCAN field being changed in an arbitrary number of records. */ scan_element *pse; scan_element *prev = NULL; scan_element *next = NULL; epicsMutexMustLock(psl->lock); psl->modified = FALSE; pse = (scan_element *)ellFirst(&psl->list); if (pse) next = (scan_element *)ellNext(&pse->node); epicsMutexUnlock(psl->lock); while (pse) { struct dbCommon *precord = pse->precord; dbScanLock(precord); dbProcess(precord); dbScanUnlock(precord); epicsMutexMustLock(psl->lock); if (!psl->modified) { prev = pse; pse = (scan_element *)ellNext(&pse->node); if (pse) next = (scan_element *)ellNext(&pse->node); } else if (pse->pscan_list == psl) { /*This scan element is still in same scan list*/ prev = pse; pse = (scan_element *)ellNext(&pse->node); if (pse) next = (scan_element *)ellNext(&pse->node); psl->modified = FALSE; } else if (prev && prev->pscan_list == psl) { /*Previous scan element is still in same scan list*/ pse = (scan_element *)ellNext(&prev->node); if (pse) { prev = (scan_element *)ellPrevious(&pse->node); next = (scan_element *)ellNext(&pse->node); } psl->modified = FALSE; } else if (next && next->pscan_list == psl) { /*Next scan element is still in same scan list*/ pse = next; prev = (scan_element *)ellPrevious(&pse->node); next = (scan_element *)ellNext(&pse->node); psl->modified = FALSE; } else { /*Too many changes. Just wait till next period*/ epicsMutexUnlock(psl->lock); return; } epicsMutexUnlock(psl->lock); } }
/* * Process a record if its scan field is passive. * Will notify if processing is complete by callback. * (only if you are interested in completion) */ long dbScanPassive(dbCommon *pfrom, dbCommon *pto) { /* if not passive just return success */ if (pto->scan != 0) return 0; if (pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto); return dbProcess(pto); }
/* * Process a record if its scan field is passive. * Will notify if processing is complete by callback. * (only if you are interested in completion) */ long epicsShareAPI dbScanPassive(dbCommon *pfrom, dbCommon *pto) { long status; /* if not passive just return success */ if(pto->scan != 0) return(0); if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto); status = dbProcess(pto); return(status); }
/*KLUDGE: Following needed so that dbPutLink to PROC field works correctly*/ long epicsShareAPI dbScanLink(dbCommon *pfrom, dbCommon *pto) { long status; unsigned char pact; if(pfrom && pfrom->ppn) dbNotifyAdd(pfrom,pto); pact = pfrom->pact; pfrom->pact = TRUE; status = dbProcess(pto); pfrom->pact = pact; return(status); }
static long subIfNetworkCalc(subRecord *precord) { #if 1 DBADDR *pdbAddrA = dbGetPdbAddrFromLink(&precord->inpa); DBADDR *pdbAddrB = dbGetPdbAddrFromLink(&precord->inpb); DBADDR *pdbAddrC = dbGetPdbAddrFromLink(&precord->inpc); DBADDR *pdbAddrD = dbGetPdbAddrFromLink(&precord->inpd); DBADDR *pdbAddrE = dbGetPdbAddrFromLink(&precord->inpe); DBADDR *pdbAddrF = dbGetPdbAddrFromLink(&precord->inpf); //double *pfieldLinkA = (double*)&pdbAddrA->pfield; //double *pfieldLinkB = (double*)&pdbAddrB->pfield; if(!pdbAddrA || !pdbAddrB || !pdbAddrC || !pdbAddrD || !pdbAddrE || !pdbAddrF) return (1); aiRecord *pairecordLinkA = (aiRecord *)pdbAddrA->precord; aiRecord *pairecordLinkB = (aiRecord *)pdbAddrB->precord; aiRecord *pairecordLinkC = (aiRecord *)pdbAddrC->precord; aiRecord *pairecordLinkD = (aiRecord *)pdbAddrD->precord; aiRecord *pairecordLinkE = (aiRecord *)pdbAddrE->precord; aiRecord *pairecordLinkF = (aiRecord *)pdbAddrF->precord; #if 0 unsigned char pact = precord->pact; if(precord->udf == FALSE) { recGblSetSevr(precord, UDF_ALARM, INVALID_ALARM); return 1; }; #endif #if 1 pifdriver->IfGetstats(); //pifdriver->PrintByte(); //printf("OutKB:%fKB, InKB:%fKB \n", pifdriver->DiffKByteOut(5), pifdriver->DiffKByteIn(5)); //pairecordLinkA->val = pifdriver->DiffKByteIn(5); //pairecordLinkB->val = pifdriver->DiffKByteOut(5); //pifdriver->DiffKByteCalc(pairecordLinkA->val,pairecordLinkB->val,5); if(pifdriver->IsEth1() == 0) pifdriver->DiffKByteCalc(pairecordLinkA->val,pairecordLinkB->val,precord->scan); else if(pifdriver->IsEth1() == 1 && pifdriver->IsEth2() == 0 ) pifdriver->DiffKByteCalc(pairecordLinkA->val,pairecordLinkB->val, pairecordLinkC->val,pairecordLinkD->val, precord->scan); else pifdriver->DiffKByteCalc(pairecordLinkA->val,pairecordLinkB->val, pairecordLinkC->val,pairecordLinkD->val, pairecordLinkE->val,pairecordLinkF->val, precord->scan); #endif #endif dbProcess((dbCommon*)pairecordLinkA); dbProcess((dbCommon*)pairecordLinkB); dbProcess((dbCommon*)pairecordLinkC); dbProcess((dbCommon*)pairecordLinkD); dbProcess((dbCommon*)pairecordLinkE); dbProcess((dbCommon*)pairecordLinkF); return (0); }
static void putNotifyCommon(putNotify *ppn,dbCommon *precord) { long status=0; dbFldDes *pfldDes = ppn->paddr->pfldDes; putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; if(precord->ppn && pputNotifyPvt->state!=putNotifyRestartCallbackRequested) { /*another putNotify owns the record */ pputNotifyPvt->state = putNotifyWaitForRestart; ellSafeAdd(&precord->ppnr->restartList,&ppn->restartNode); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } else if(precord->ppn){ assert(precord->ppn==ppn); assert(pputNotifyPvt->state==putNotifyRestartCallbackRequested); } if(precord->pact) { precord->ppn = ppn; ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); pputNotifyPvt->state = putNotifyRestartInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } status=dbPut(ppn->paddr,ppn->dbrType,ppn->pbuffer,ppn->nRequest); ppn->status = (status==0) ? putNotifyOK : putNotifyError; /* Check to see if dbProcess should not be called */ if(!status /*dont process if dbPut returned error */ &&((ppn->paddr->pfield==(void *)&precord->proc) /*If PROC call dbProcess*/ || (pfldDes->process_passive && precord->scan==0))) { precord->ppn = ppn; ellSafeAdd(&pputNotifyPvt->waitList,&precord->ppnr->waitNode); pputNotifyPvt->state = putNotifyPutInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbProcess(precord); dbScanUnlock(precord); return; } if(pputNotifyPvt->state==putNotifyRestartCallbackRequested) { restartCheck(precord->ppnr); } pputNotifyPvt->state = putNotifyUserCallbackActive; assert(precord->ppn!=ppn); callUser(precord,ppn); }
long epicsShareAPI dbPutField(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest) { long status = 0; long special = paddr->special; dbFldDes *pfldDes = paddr->pfldDes; dbCommon *precord = paddr->precord; short dbfType = paddr->field_type; if (special == SPC_ATTRIBUTE) return S_db_noMod; /*check for putField disabled*/ if (precord->disp && (void *)(&precord->disp) != paddr->pfield) return S_db_putDisabled; if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) return dbPutFieldLink(paddr, dbrType, pbuffer, nRequest); dbScanLock(precord); status = dbPut(paddr, dbrType, pbuffer, nRequest); if (status == 0) { if (paddr->pfield == (void *)&precord->proc || (pfldDes->process_passive && precord->scan == 0 && dbrType < DBR_PUT_ACKT)) { if (precord->pact) { if (precord->tpro) printf("%s: Active %s\n", epicsThreadGetNameSelf(), precord->name); precord->rpro = TRUE; } else { /* indicate that dbPutField called dbProcess */ precord->putf = TRUE; status = dbProcess(precord); } } } dbScanUnlock(precord); return status; }
static void myCallbackFunc(CALLBACK *arg) { myCallback *pcallback; boRecord *prec; callbackGetUser(pcallback,arg); prec=(boRecord *)pcallback->precord; dbScanLock((struct dbCommon *)prec); if(prec->pact) { if((prec->val==1) && (prec->high>0)){ myCallback *pcallback; pcallback = (myCallback *)(prec->rpvt); callbackSetPriority(prec->prio, &pcallback->callback); callbackRequestDelayed(&pcallback->callback,(double)prec->high); } } else { prec->val = 0; dbProcess((struct dbCommon *)prec); } dbScanUnlock((struct dbCommon *)prec); }
static void onceTask(void *arg) { taskwdInsert(0, NULL, NULL); epicsEventSignal(startStopEvent); while (TRUE) { void *precord; epicsEventMustWait(onceSem); while ((precord = epicsRingPointerPop(onceQ))) { if (precord == &exitOnce) goto shutdown; dbScanLock(precord); dbProcess(precord); dbScanUnlock(precord); } } shutdown: taskwdRemove(0); epicsEventSignal(startStopEvent); }
/* * Process a record without printing it. */ long epicsShareAPI dbprc(char *record_name) { struct dbAddr addr; struct dbCommon *precord; long status; /* * Convert name to address */ status = dbNameToAddr(record_name, &addr); if (status == S_db_notFound) printf(" BKPT> Record %s not found\n", record_name); if (status != 0) return(status); precord = addr.precord; /* lock lockset, process record, unlock lockset */ dbScanLock(precord); status = dbProcess(precord); dbScanUnlock(precord); return(status); }
/* * Task for continuing record processing * 1. Find lockset in stack for precord. * DO 2-3 while breakpoints exist in the lockset. * 2. Wait on execution semaphore ... * 3. Run through every entrypoint in queue, processing * those that are scheduled. * 4. Free resources for lockset, and exit task. */ static void dbBkptCont(dbCommon *precord) { struct LS_LIST *pnode; struct EP_LIST *pqe = NULL; /* * Reset breakpoint, process record, and * reset bkpt field in record */ epicsMutexMustLock(bkpt_stack_sem); FIND_LOCKSET(precord, pnode); if (pnode == NULL) { printf(" BKPT> Logic error in dbBkptCont()\n"); return; } /* * For every entrypoint scheduled, process. Run process * until there are no more breakpoints remaining in a * lock set. */ do { /* Give up semaphore before waiting to run ... */ epicsMutexUnlock(bkpt_stack_sem); /* Wait to run */ epicsEventMustWait(pnode->ex_sem); /* Bkpt stack must still be stable ! */ epicsMutexMustLock(bkpt_stack_sem); pqe = (struct EP_LIST *) ellFirst(&pnode->ep_queue); /* Run through entrypoint queue */ while (pqe != NULL) { /* check if entrypoint is currently scheduled */ if (pqe->sched) { /* save current entrypoint */ pnode->current_ep = pqe->entrypoint; /* lock the lockset, process record, unlock */ dbScanLock(precord); dbProcess(pqe->entrypoint); dbScanUnlock(precord); /* reset schedule and stepping flag - Do this AFTER processing */ pqe->sched = 0; pnode->step = 0; } pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe); } /* Reset precord. (Since no records are at a breakpoint) */ pnode->precord = NULL; } while (ellCount(&pnode->bp_list) != 0); /* remove node from lockset stack */ ellDelete(&lset_stack, (ELLNODE *)pnode); --lset_stack_count; /* free entrypoint queue */ ellFree(&pnode->ep_queue); /* remove execution semaphore */ epicsEventDestroy(pnode->ex_sem); printf("\n BKPT> End debug of lockset %lu\n-> ", pnode->l_num); /* free list node */ free(pnode); epicsMutexUnlock(bkpt_stack_sem); }
static void processNotifyCommon(processNotify *ppn,dbCommon *precord) { notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; int didPut = 0; int doProcess = 0; if (precord->ppn && pnotifyPvt->state != notifyRestartCallbackRequested) { /* Another processNotify owns the record */ pnotifyPvt->state = notifyWaitForRestart; ellSafeAdd(&precord->ppnr->restartList, &ppn->restartNode); epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } else if (precord->ppn) { assert(precord->ppn == ppn); assert(pnotifyPvt->state == notifyRestartCallbackRequested); } if (precord->pact) { precord->ppn = ppn; ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode); pnotifyPvt->state = notifyRestartInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbScanUnlock(precord); return; } 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 { didPut = ppn->putCallback(ppn, putType); } } /* Check if dbProcess should be called */ if (didPut && ((dbChannelField(ppn->chan) == (void *) &precord->proc) || (dbChannelFldDes(ppn->chan)->process_passive && precord->scan == 0))) doProcess = 1; else if (ppn->requestType == processGetRequest && precord->scan == 0) doProcess = 1; if (doProcess) { ppn->wasProcessed = 1; precord->ppn = ppn; ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode); pnotifyPvt->state = notifyProcessInProgress; epicsMutexUnlock(pnotifyGlobal->lock); dbProcess(precord); dbScanUnlock(precord); return; } if (pnotifyPvt->state == notifyRestartCallbackRequested) { restartCheck(precord->ppnr); } pnotifyPvt->state = notifyUserCallbackActive; assert(precord->ppn!=ppn); callDone(precord, ppn); }
static void testFIFOCirc(void) { aiRecord *vrec; compressRecord *crec; double *cbuf; testDiag("Test FIFO"); testdbPrepare(); testdbReadDatabase("recTestIoc.dbd", NULL, NULL); recTestIoc_registerRecordDeviceDriver(pdbbase); testdbReadDatabase("compressTest.db", NULL, "ALG=Circular Buffer,BALG=FIFO Buffer,NSAM=4"); vrec = (aiRecord*)testdbRecordPtr("val"); crec = (compressRecord*)testdbRecordPtr("comp"); eltc(0); testIocInitOk(); eltc(1); dbScanLock((dbCommon*)crec); cbuf = crec->bptr; testOk1(crec->off==0); testOk1(crec->inx==0); testOk1(crec->nuse==0); testDiag("Push 1.1"); vrec->val = 1.1; dbProcess((dbCommon*)crec); /* In FIFO mode the valid elements are * cbuf[(off-nuse-1) % size] through cbuf[(off-1) % size] */ testOk1(crec->off==1); testOk1(crec->inx==0); testOk1(crec->nuse==1); testDEq(cbuf[0], 1.1, 0.1); testDEq(cbuf[1], 0.0, 0.1); testDEq(cbuf[2], 0.0, 0.1); testDEq(cbuf[3], 0.0, 0.1); checkArrD("comp", 1, 1.1, 0, 0, 0); testDiag("Push 2.1"); vrec->val = 2.1; dbProcess((dbCommon*)crec); testOk1(crec->off==2); testOk1(crec->inx==0); testOk1(crec->nuse==2); testDEq(cbuf[0], 1.1, 0.1); testDEq(cbuf[1], 2.1, 0.1); testDEq(cbuf[2], 0.0, 0.1); testDEq(cbuf[3], 0.0, 0.1); checkArrD("comp", 2, 1.1, 2.1, 0, 0); testDiag("Push 3.1"); vrec->val = 3.1; dbProcess((dbCommon*)crec); testOk1(crec->off==3); testOk1(crec->inx==0); testOk1(crec->nuse==3); testDEq(cbuf[0], 1.1, 0.1); testDEq(cbuf[1], 2.1, 0.1); testDEq(cbuf[2], 3.1, 0.1); testDEq(cbuf[3], 0.0, 0.1); checkArrD("comp", 3, 1.1, 2.1, 3.1, 0); testDiag("Push 4.1"); vrec->val = 4.1; dbProcess((dbCommon*)crec); testOk1(crec->off==0); testOk1(crec->inx==0); testOk1(crec->nuse==4); testDEq(cbuf[0], 1.1, 0.1); testDEq(cbuf[1], 2.1, 0.1); testDEq(cbuf[2], 3.1, 0.1); testDEq(cbuf[3], 4.1, 0.1); checkArrD("comp", 4, 1.1, 2.1, 3.1, 4.1); testDiag("Push 5.1"); vrec->val = 5.1; dbProcess((dbCommon*)crec); testOk1(crec->off==1); testOk1(crec->inx==0); testOk1(crec->nuse==4); testDEq(cbuf[0], 5.1, 0.1); testDEq(cbuf[1], 2.1, 0.1); testDEq(cbuf[2], 3.1, 0.1); testDEq(cbuf[3], 4.1, 0.1); checkArrD("comp", 4, 2.1, 3.1, 4.1, 5.1); testDiag("Push 6.1"); vrec->val = 6.1; dbProcess((dbCommon*)crec); testOk1(crec->off==2); testOk1(crec->inx==0); testOk1(crec->nuse==4); testDEq(cbuf[0], 5.1, 0.1); testDEq(cbuf[1], 6.1, 0.1); testDEq(cbuf[2], 3.1, 0.1); testDEq(cbuf[3], 4.1, 0.1); checkArrD("comp", 4, 3.1, 4.1, 5.1, 6.1); dbScanUnlock((dbCommon*)crec); testDiag("Reset"); testdbPutFieldOk("comp.RES", DBF_LONG, 0); dbScanLock((dbCommon*)crec); testOk1(crec->off==0); testOk1(crec->inx==0); testOk1(crec->nuse==0); checkArrD("comp", 0, 0, 0, 0, 0); dbScanUnlock((dbCommon*)crec); testIocShutdownOk(); testdbCleanup(); }