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 char *msgbufGetFree(int noConsoleMessage) { msgNode *pnextSend; if (epicsMutexLock(pvtData.msgQueueLock) != epicsMutexLockOK) return 0; if ((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) { int nchar; pnextSend = msgbufGetNode(); nchar = sprintf(pnextSend->message, "errlog: %d messages were discarded\n", pvtData.missedMessages); pnextSend->length = nchar + 1; pvtData.missedMessages = 0; ellAdd(&pvtData.msgQueue, &pnextSend->node); } pvtData.pnextSend = pnextSend = msgbufGetNode(); if (pnextSend) { pnextSend->noConsoleMessage = noConsoleMessage; pnextSend->length = 0; return pnextSend->message; /* NB: msgQueueLock is still locked */ } ++pvtData.missedMessages; epicsMutexUnlock(pvtData.msgQueueLock); return 0; }
static void createChannelCallFunction(const iocshArgBuf *args) { drvM6802_taskConfig *ptaskConfig = NULL; drvM6802_channelConfig *pchannelConfig = NULL; char task_name[60]; char channel_name[60]; int channel_ID=0; if(args[0].sval) strcpy(task_name, args[0].sval); if(args[1].sval) channel_ID = strtoul(args[1].sval,NULL,0); if(args[2].sval) strcpy(channel_name, args[2].sval); ptaskConfig = find_taskConfig(task_name); if(!ptaskConfig) return; pchannelConfig = (drvM6802_channelConfig*) malloc(sizeof(drvM6802_channelConfig)); if(!pchannelConfig) return; pchannelConfig->channelStatus = 0x0000; strcpy(pchannelConfig->chanName, channel_name); pchannelConfig->chanIndex = channel_ID; pchannelConfig->gain = INIT_GAIN; pchannelConfig->ptaskConfig = ptaskConfig; pchannelConfig->conversionTime_usec = 0.; ellAdd(ptaskConfig->pchannelConfig, &pchannelConfig->node); #ifdef DEBUG epicsPrintf("createChannelCallFunction... ok\n"); #endif /* DEBUG */ return; }
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); }
int epicsJobMove(epicsJob *job, epicsThreadPool *newpool) { epicsThreadPool *pool = job->pool; /* remove from current pool */ if (pool) { epicsMutexMustLock(pool->guard); if (job->queued || job->running) { epicsMutexUnlock(pool->guard); return S_pool_jobBusy; } ellDelete(&pool->owned, &job->jobnode); epicsMutexUnlock(pool->guard); } pool = job->pool = newpool; /* add to new pool */ if (pool) { epicsMutexMustLock(pool->guard); ellAdd(&pool->owned, &job->jobnode); epicsMutexUnlock(pool->guard); } return 0; }
void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr) { struct tNode *pt; struct mNode *pm; taskwdInit(); if (tid == 0) tid = epicsThreadGetIdSelf(); pt = &allocNode()->t; pt->tid = tid; pt->callback = callback; pt->usr = usr; pt->suspended = FALSE; epicsMutexMustLock(mLock); pm = (struct mNode *)ellFirst(&mList); while (pm) { if (pm->funcs->insert) { pm->funcs->insert(pm->usr, tid); } pm = (struct mNode *)ellNext(&pm->node); } epicsMutexUnlock(mLock); epicsMutexMustLock(tLock); ellAdd(&tList, (void *)pt); epicsMutexUnlock(tLock); }
/* * Driver initialisation at IOC startup (ecAsynInit) * * path - location of Unix Domain Socket, must match the scanner's * max_message - maximum size of messages between scanner and ioc * This must be able to accommodate the configuration * of the chain that is transferred from the scanner to * the ioc. */ static void makePorts(char * path, int max_message) { ENGINE_USER * usr = (ENGINE_USER *)callocMustSucceed (1, sizeof(ENGINE_USER), "can't allocate socket engine private data"); ellInit(&usr->ports); usr->master = new ecMaster((char *)"MASTER0"); ellAdd(&usr->ports, &usr->master->node); usr->config_ready = rtMessageQueueCreate(1, sizeof(int)); // TODO - no assert for runtime errors, so what should we use to throw? assert(usr->config_ready != NULL); usr->config = (EC_CONFIG *)callocMustSucceed (1, sizeof(EC_CONFIG), "can't allocate chain config lists"); usr->writeq = rtMessageQueueCreate(1, max_message); assert(usr->writeq != NULL); ENGINE * engine = new_engine(max_message); engine->path = strdup(path); engine->connect = client_connect; engine->on_connect = receive_config_on_connect; engine->send_message = ioc_send; engine->receive_message = ioc_receive; engine->usr = usr; engine_start(engine); new_timer(1000000000, usr->writeq, 0, MSG_HEARTBEAT); int ack; rtMessageQueueReceive(usr->config_ready, &ack, sizeof(int)); }
int epicsJobUnqueue(epicsJob *job) { int ret = S_pool_jobIdle; epicsThreadPool *pool = job->pool; if (!pool) return S_pool_noPool; epicsMutexMustLock(pool->guard); assert(!job->dead); if (job->queued) { if (!job->running) { ellDelete(&pool->jobs, &job->jobnode); ellAdd(&pool->owned, &job->jobnode); } job->queued = 0; ret = 0; } epicsMutexUnlock(pool->guard); return ret; }
motorSimController::motorSimController(const char *portName, int numAxes, int priority, int stackSize) : asynMotorController(portName, numAxes, NUM_SIM_CONTROLLER_PARAMS, asynInt32Mask | asynFloat64Mask, asynInt32Mask | asynFloat64Mask, ASYN_CANBLOCK | ASYN_MULTIDEVICE, 1, // autoconnect priority, stackSize) { int axis; motorSimControllerNode *pNode; if (!motorSimControllerListInitialized) { motorSimControllerListInitialized = 1; ellInit(&motorSimControllerList); } // We should make sure this portName is not already in the list */ pNode = (motorSimControllerNode*) calloc(1, sizeof(motorSimControllerNode)); pNode->portName = epicsStrDup(portName); pNode->pController = this; ellAdd(&motorSimControllerList, (ELLNODE *)pNode); if (numAxes < 1 ) numAxes = 1; numAxes_ = numAxes; this->movesDeferred_ = 0; for (axis=0; axis<numAxes; axis++) { new motorSimAxis(this, axis, DEFAULT_LOW_LIMIT, DEFAULT_HI_LIMIT, DEFAULT_HOME, DEFAULT_START); setDoubleParam(axis, this->motorPosition_, DEFAULT_START); } this->motorThread_ = epicsThreadCreate("motorSimThread", epicsThreadPriorityLow, epicsThreadGetStackSize(epicsThreadStackMedium), (EPICSTHREADFUNC) motorSimTaskC, (void *) this); }
static void * start_routine(void *arg) { epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg; int status; int oldtype; sigset_t blockAllSig; sigfillset(&blockAllSig); pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL); status = pthread_setspecific(getpthreadInfo,arg); checkStatusQuit(status,"pthread_setspecific","start_routine"); status = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype); checkStatusQuit(status,"pthread_setcanceltype","start_routine"); status = mutexLock(&listLock); checkStatusQuit(status,"pthread_mutex_lock","start_routine"); ellAdd(&pthreadList,&pthreadInfo->node); pthreadInfo->isOnThreadList = 1; status = pthread_mutex_unlock(&listLock); checkStatusQuit(status,"pthread_mutex_unlock","start_routine"); (*pthreadInfo->createFunc)(pthreadInfo->createArg); epicsExitCallAtThreadExits (); free_threadInfo(pthreadInfo); return(0); }
/* * devInsertAddress() */ static void devInsertAddress( ELLLIST *pRangeList, rangeItem *pNewRange) { rangeItem *pBefore; rangeItem *pAfter; epicsMutexMustLock(addrListLock); pAfter = (rangeItem *) ellFirst (pRangeList); while (pAfter) { if (pNewRange->end < pAfter->begin) { break; } pAfter = (rangeItem *) ellNext (&pAfter->node); } if (pAfter) { pBefore = (rangeItem *) ellPrevious (&pAfter->node); ellInsert (pRangeList, &pBefore->node, &pNewRange->node); } else { ellAdd (pRangeList, &pNewRange->node); } epicsMutexUnlock(addrListLock); }
void bufRxManager::received(CALLBACK* cb) { void *vptr; callbackGetUser(vptr,cb); bufRxManager &self=*static_cast<bufRxManager*>(vptr); SCOPED_LOCK2(self.guard, G); while(true) { ELLNODE *node=ellGet(&self.usedbufs); if (!node) break; buffer *buf=CONTAINER(node, buffer, node); G.unlock(); for(ELLNODE *cur=ellFirst(&self.dispatch); cur; cur=ellNext(cur)) { listener *action=CONTAINER(cur, listener, node); (action->fn)(action->fnarg, 0, buf->used, buf->data); } G.lock(); ellAdd(&self.freebufs, &buf->node); }; }
void dbRegisterFilter(const char *name, const chFilterIf *fif, void *puser) { GPHENTRY *pgph; chFilterPlugin *pfilt; if (!pdbbase) { printf("dbRegisterFilter: pdbbase not set!\n"); return; } pgph = gphFind(pdbbase->pgpHash, name, &pdbbase->filterList); if (pgph) return; pfilt = dbCalloc(1, sizeof(chFilterPlugin)); pfilt->name = epicsStrDup(name); pfilt->fif = fif; pfilt->puser = puser; ellAdd(&pdbbase->filterList, &pfilt->node); pgph = gphAdd(pdbbase->pgpHash, pfilt->name, &pdbbase->filterList); if (!pgph) { free((void *) pfilt->name); free(pfilt); printf("dbRegisterFilter: gphAdd failed\n"); return; } pgph->userPvt = pfilt; }
static void freeNode(union twdNode *pn) { VALGRIND_MEMPOOL_FREE(&fList, pn); VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(ELLNODE)); epicsMutexMustLock(fLock); ellAdd(&fList, (void *)pn); epicsMutexUnlock(fLock); }
static void notifyCleanup(processNotify *ppn) { notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; pnotifyPvt->state = notifyNotActive; ellAdd(&pnotifyGlobal->freeList, &pnotifyPvt->node); ppn->pnotifyPvt = 0; }
static void allocTemp(void *pvoid) { tempListNode *ptempListNode; ptempListNode = freeListCalloc(freeListPvt); ptempListNode->item = pvoid; ellAdd(&tempList,&ptempListNode->node); }
static void putNotifyCleanup(putNotify *ppn) { putNotifyPvt *pputNotifyPvt = (putNotifyPvt *)ppn->pputNotifyPvt; pputNotifyPvt->state = putNotifyNotActive; ellAdd(&pnotifyGlobal->freeList,&pputNotifyPvt->node); ppn->pputNotifyPvt = 0; }
static void msgbufSetSize(int size) { msgNode *pnextSend = pvtData.pnextSend; pnextSend->length = size+1; ellAdd(&pvtData.msgQueue, &pnextSend->node); epicsMutexUnlock(pvtData.msgQueueLock); epicsEventSignal(pvtData.waitForWork); }
epicsShareFunc epicsThreadPool* epicsThreadPoolGetShared(epicsThreadPoolConfig *opts) { ELLNODE *node; epicsThreadPool *cur; epicsThreadPoolConfig defopts; size_t N = epicsThreadGetCPUs(); if (!opts) { epicsThreadPoolConfigDefaults(&defopts); opts = &defopts; } /* shared pools must have a minimum allowed number of workers. * Use the number of CPU cores */ if (opts->maxThreads < N) opts->maxThreads = N; epicsThreadOnce(&sharedPoolsOnce, &sharedPoolsInit, NULL); epicsMutexMustLock(sharedPoolsGuard); for (node = ellFirst(&sharedPools); node; node = ellNext(node)) { cur = CONTAINER(node, epicsThreadPool, sharedNode); /* Must have exactly the requested priority * At least the requested max workers * and at least the requested stack size */ if (cur->conf.workerPriority != opts->workerPriority) continue; if (cur->conf.maxThreads < opts->maxThreads) continue; if (cur->conf.workerStack < opts->workerStack) continue; cur->sharedCount++; assert(cur->sharedCount > 0); epicsMutexUnlock(sharedPoolsGuard); epicsMutexMustLock(cur->guard); *opts = cur->conf; epicsMutexUnlock(cur->guard); return cur; } cur = epicsThreadPoolCreate(opts); if (!cur) { epicsMutexUnlock(sharedPoolsGuard); return NULL; } cur->sharedCount = 1; ellAdd(&sharedPools, &cur->sharedNode); epicsMutexUnlock(sharedPoolsGuard); return cur; }
/** Adds an attribute to the list. * If an attribute of the same name already exists then * the existing attribute is deleted and replaced with the new one. * \param[in] pAttribute A pointer to the attribute to add. */ int NDAttributeList::add(NDAttribute *pAttribute) { //const char *functionName = "NDAttributeList::add"; epicsMutexLock(this->lock); /* Remove any existing attribute with this name */ this->remove(pAttribute->pName); ellAdd(&this->list, &pAttribute->listNode.node); epicsMutexUnlock(this->lock); return(ND_SUCCESS); }
static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg) { int status = -1; exitNode * pExitNode = calloc ( 1, sizeof( *pExitNode ) ); if ( pExitNode ) { pExitNode->func = func; pExitNode->arg = arg; ellAdd ( & pep->list, & pExitNode->node ); status = 0; } return status; }
/* * removeDuplicateAddresses () */ extern "C" void epicsShareAPI removeDuplicateAddresses ( ELLLIST *pDestList, ELLLIST *pSrcList, int silent ) { ELLNODE *pRawNode; while ( (pRawNode = ellGet ( pSrcList ) ) ) { STATIC_ASSERT ( offsetof (osiSockAddrNode, node) == 0 ); osiSockAddrNode *pNode = reinterpret_cast <osiSockAddrNode *> ( pRawNode ); osiSockAddrNode *pTmpNode; if ( pNode->addr.sa.sa_family == AF_INET ) { pTmpNode = (osiSockAddrNode *) ellFirst (pDestList); // X aCC 749 while ( pTmpNode ) { if (pTmpNode->addr.sa.sa_family == AF_INET) { if ( pNode->addr.ia.sin_addr.s_addr == pTmpNode->addr.ia.sin_addr.s_addr && pNode->addr.ia.sin_port == pTmpNode->addr.ia.sin_port ) { if ( ! silent ) { char buf[64]; ipAddrToDottedIP ( &pNode->addr.ia, buf, sizeof (buf) ); fprintf ( stderr, "Warning: Duplicate EPICS CA Address list entry \"%s\" discarded\n", buf ); } free (pNode); pNode = NULL; break; } } pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node); // X aCC 749 } if (pNode) { ellAdd (pDestList, &pNode->node); } } else { ellAdd (pDestList, &pNode->node); } } }
dbStateId dbStateCreate(const char *name) { dbStateId id; if ((id = dbStateFind(name))) return id; id = callocMustSucceed(1, sizeof(dbState), "createDbState"); id->name = epicsStrDup(name); id->lock = epicsMutexMustCreate(); ellAdd(&states, &id->node); return id; }
static void readConfig(ENGINE_USER * usr) { EC_CONFIG * cfg = usr->config; ELLNODE * node; int ndev = 0; for(node = ellFirst(&cfg->devices); node; node = ellNext(node)) { EC_DEVICE * device = (EC_DEVICE *)node; printf("Creating ecAsyn port No %d: %s\n", ndev, device->name); ecAsyn * port = new ecAsyn(device, device->pdo_entry_mappings.count, device->sdo_requests.count, usr, ndev); ellAdd(&usr->ports, &port->node); if (port->sdos > 0) { char *sdoportname= format("%s_SDO", device->name); ecSdoAsyn * sdoport = new ecSdoAsyn(sdoportname, port); ellAdd(&usr->sdo_observers, &sdoport->node); free(sdoportname); } ndev++; } }
bool addToList(const char *portName, PMCVController *drv) { if (!PMCVListInitialized) { PMCVListInitialized = 1; ellInit(&PMCVList); } else if (findByPortName(portName) != NULL) { fprintf(stderr, "ERROR: Re-using portName=%s\n", portName); return false; } PMCVNode *pNode = (PMCVNode*)calloc(1, sizeof(PMCVNode)); pNode->portName = epicsStrDup(portName); pNode->pController = drv; ellAdd(&PMCVList, (ELLNODE*)pNode); return true; }
static void dbRecordtypeCdef(char *text) { dbText *pdbCdef; tempListNode *ptempListNode; dbRecordType *pdbRecordType; if (!pdbbase->loadCdefs || duplicate) return; ptempListNode = (tempListNode *)ellFirst(&tempList); pdbRecordType = ptempListNode->item; pdbCdef = dbCalloc(1,sizeof(dbText)); if (text[0] == ' ') text++; /* strip leading space if present */ pdbCdef->text = epicsStrDup(text); ellAdd(&pdbRecordType->cdefList, &pdbCdef->node); return; }
static void chf_value(parseContext *parser, parse_result *presult) { chFilter *filter = parser->filter; if (*presult == parse_stop || parser->depth > 0) return; parser->filter = NULL; if (filter->plug->fif->parse_end(filter) == parse_continue) { ellAdd(&parser->chan->filters, &filter->list_node); } else { freeListFree(chFilterFreeList, filter); *presult = parse_stop; } }
static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg, const char *name) { int status = -1; exitNode * pExitNode = calloc ( 1, sizeof( *pExitNode ) + (name?strlen(name):0) ); if ( pExitNode ) { pExitNode->func = func; pExitNode->arg = arg; if(name) strcpy(pExitNode->name, name); ellAdd ( & pep->list, & pExitNode->node ); status = 0; } return status; }
void taskwdMonitorAdd(const taskwdMonitor *funcs, void *usr) { struct mNode *pm; if (funcs == NULL) return; taskwdInit(); pm = &allocNode()->m; pm->funcs = funcs; pm->usr = usr; epicsMutexMustLock(mLock); ellAdd(&mList, (void *)pm); epicsMutexUnlock(mLock); }
/** Adds an attribute to the list. * This is a convenience function for adding attributes to a list. * It first searches the list to see if there is an existing attribute * with the same name. If there is it just changes the properties of the * existing attribute. If not, it creates a new attribute with the * specified properties. * IMPORTANT: This method is only capable of creating attributes * of the NDAttribute base class type, not derived class attributes. * To add attributes of a derived class to a list the NDAttributeList::add(NDAttribute*) * method must be used. * \param[in] pName The name of the attribute to be added. * \param[in] pDescription The description of the attribute. * \param[in] dataType The data type of the attribute. * \param[in] pValue A pointer to the value for this attribute. * */ NDAttribute* NDAttributeList::add(const char *pName, const char *pDescription, NDAttrDataType_t dataType, void *pValue) { //const char *functionName = "NDAttributeList::add"; NDAttribute *pAttribute; epicsMutexLock(this->lock); pAttribute = this->find(pName); if (pAttribute) { pAttribute->setDescription(pDescription); pAttribute->setValue(dataType, pValue); } else { pAttribute = new NDAttribute(pName, pDescription, dataType, pValue); ellAdd(&this->list, &pAttribute->listNode.node); } epicsMutexUnlock(this->lock); return(pAttribute); }