static void getCallbackValue(devInt32Pvt *pPvt) { int count, size=sizeof(epicsInt32); epicsMutexLock(pPvt->mutexId); if (pPvt->ringBuffer && (epicsRingBytesUsedBytes(pPvt->ringBuffer) >= size)) { if (pPvt->ringBufferOverflows > 0) { asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynInt32 getCallbackValue error, %d ring buffer overflows\n", pPvt->pr->name, pPvt->ringBufferOverflows); pPvt->ringBufferOverflows = 0; } count = epicsRingBytesGet(pPvt->ringBuffer, (char *)&pPvt->value, size); if (count == size) { asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE, "%s devAsynInt32::getCallbackValue from ringBuffer value=%d\n",pPvt->pr->name,pPvt->value); pPvt->gotValue = 1; } else asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, "%s devAsynInt32 getCallbackValue error, ring read failed\n", pPvt->pr->name); } epicsMutexUnlock(pPvt->mutexId); }
static void check(epicsRingBytesId ring, int expectedFree) { int expectedUsed = RINGSIZE - expectedFree; int expectedEmpty = (expectedUsed == 0); int expectedFull = (expectedFree == 0); int nFree = epicsRingBytesFreeBytes(ring); int nUsed = epicsRingBytesUsedBytes(ring); int isEmpty = epicsRingBytesIsEmpty(ring); int isFull = epicsRingBytesIsFull(ring); testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree); testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed); testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty); testOk(isFull == expectedFull, "Full: %d == %d", isFull, expectedFull); }
asynStatus drvQuadEM::doDataCallbacks() { epicsFloat64 doubleData[QE_MAX_DATA]; epicsFloat64 *pIn, *pOut; int numAverage; int numAveraged; int sampleSize = sizeof(doubleData); int count; epicsTimeStamp now; epicsFloat64 timeStamp; int arrayCounter; int i, j; size_t dims[2]; NDArray *pArrayAll, *pArraySingle; static const char *functionName = "doDataCallbacks"; getIntegerParam(P_NumAverage, &numAverage); while (1) { numAveraged = epicsRingBytesUsedBytes(ringBuffer_) / sampleSize; if (numAverage > 0) { if (numAveraged < numAverage) break; numAveraged = numAverage; setIntegerParam(P_NumAveraged, numAveraged); } else { setIntegerParam(P_NumAveraged, numAveraged); if (numAveraged < 1) break; } dims[0] = QE_MAX_DATA; dims[1] = numAveraged; epicsTimeGetCurrent(&now); getIntegerParam(NDArrayCounter, &arrayCounter); arrayCounter++; setIntegerParam(NDArrayCounter, arrayCounter); pArrayAll = pNDArrayPool->alloc(2, dims, NDFloat64, 0, 0); pArrayAll->uniqueId = arrayCounter; timeStamp = now.secPastEpoch + now.nsec / 1.e9; pArrayAll->timeStamp = timeStamp; getAttributes(pArrayAll->pAttributeList); count = epicsRingBytesGet(ringBuffer_, (char *)pArrayAll->pData, numAveraged * sampleSize); if (count != numAveraged * sampleSize) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: ring read failed\n", driverName, functionName); return asynError; } ringCount_ -= numAveraged; unlock(); doCallbacksGenericPointer(pArrayAll, NDArrayData, QE_MAX_DATA); lock(); // Copy data to arrays for each type of data, do callbacks on that. dims[0] = numAveraged; for (i=0; i<QE_MAX_DATA; i++) { pArraySingle = pNDArrayPool->alloc(1, dims, NDFloat64, 0, 0); pArraySingle->uniqueId = arrayCounter; pArraySingle->timeStamp = timeStamp; getAttributes(pArraySingle->pAttributeList); pIn = (epicsFloat64 *)pArrayAll->pData; pOut = (epicsFloat64 *)pArraySingle->pData; for (j=0; j<numAveraged; j++) { pOut[j] = pIn[i]; pIn += QE_MAX_DATA; } unlock(); doCallbacksGenericPointer(pArraySingle, NDArrayData, i); lock(); pArraySingle->release(); } pArrayAll->release(); callParamCallbacks(); // We only loop once if numAverage==0 if (numAverage == 0) break; } setIntegerParam(P_RingOverflows, 0); callParamCallbacks(); return asynSuccess; }