replace osiRing with epicsRingPointer
This commit is contained in:
@@ -22,7 +22,7 @@ of this distribution.
|
||||
#include "osiThread.h"
|
||||
#include "osiInterrupt.h"
|
||||
#include "osiTimer.h"
|
||||
#include "osiRing.h"
|
||||
#include "epicsRingPointer.h"
|
||||
#include "tsStamp.h"
|
||||
#include "errlog.h"
|
||||
#include "dbStaticLib.h"
|
||||
@@ -41,7 +41,7 @@ of this distribution.
|
||||
|
||||
int callbackQueueSize = 2000;
|
||||
static semBinaryId callbackSem[NUM_CALLBACK_PRIORITIES];
|
||||
static ringId callbackQ[NUM_CALLBACK_PRIORITIES];
|
||||
static epicsRingPointerId callbackQ[NUM_CALLBACK_PRIORITIES];
|
||||
static threadId callbackTaskId[NUM_CALLBACK_PRIORITIES];
|
||||
static int ringOverflow[NUM_CALLBACK_PRIORITIES];
|
||||
static void callbackInitPvt(void *);
|
||||
@@ -92,7 +92,7 @@ void epicsShareAPI callbackInit()
|
||||
void epicsShareAPI callbackRequest(CALLBACK *pcallback)
|
||||
{
|
||||
int priority = pcallback->priority;
|
||||
int nput;
|
||||
int pushOK;
|
||||
int lockKey;
|
||||
|
||||
if(priority<0 || priority>=(NUM_CALLBACK_PRIORITIES)) {
|
||||
@@ -101,9 +101,9 @@ void epicsShareAPI callbackRequest(CALLBACK *pcallback)
|
||||
}
|
||||
if(ringOverflow[priority]) return;
|
||||
lockKey = interruptLock();
|
||||
nput = ringPut(callbackQ[priority],(void *)&pcallback,sizeof(pcallback));
|
||||
pushOK = epicsRingPointerPush(callbackQ[priority],(void *)pcallback);
|
||||
interruptUnlock(lockKey);
|
||||
if(nput!=sizeof(pcallback)){
|
||||
if(!pushOK) {
|
||||
epicsPrintf("callbackRequest ring buffer full\n");
|
||||
ringOverflow[priority] = TRUE;
|
||||
}
|
||||
@@ -116,20 +116,14 @@ static void callbackTask(int *ppriority)
|
||||
{
|
||||
int priority = *ppriority;
|
||||
CALLBACK *pcallback;
|
||||
int nget;
|
||||
|
||||
ringOverflow[priority] = FALSE;
|
||||
while(TRUE) {
|
||||
/* wait for somebody to wake us up */
|
||||
semBinaryMustTake(callbackSem[priority]);
|
||||
while(TRUE) {
|
||||
nget = ringGet(callbackQ[priority],
|
||||
(void *)&pcallback,sizeof(pcallback));
|
||||
if(nget==0) break;
|
||||
if(nget!=sizeof(pcallback)) {
|
||||
errMessage(0,"ringGet failed in callbackTask");
|
||||
threadSuspendSelf();
|
||||
}
|
||||
if(!(pcallback = (CALLBACK *)
|
||||
epicsRingPointerPop(callbackQ[priority]))) break;
|
||||
ringOverflow[priority] = FALSE;
|
||||
(*pcallback->callback)(pcallback);
|
||||
}
|
||||
@@ -150,8 +144,8 @@ static void start(int ind)
|
||||
errMessage(0,"callback start called with illegal priority\n");
|
||||
return;
|
||||
}
|
||||
if((callbackQ[ind]=ringCreate(sizeof(CALLBACK *)*callbackQueueSize)) == 0)
|
||||
errMessage(0,"ringCreate failed while starting a callback task");
|
||||
if((callbackQ[ind]=epicsRingPointerCreate(callbackQueueSize)) == 0)
|
||||
errMessage(0,"epicsRingPointerCreate failed while starting a callback task");
|
||||
sprintf(taskName,"cb%s",priorityName[ind]);
|
||||
callbackTaskId[ind] = threadCreate(taskName,priority,
|
||||
threadGetStackSize(threadStackBig),(THREADFUNC)callbackTask,
|
||||
@@ -170,7 +164,7 @@ static void wdCallback(void *pind)
|
||||
taskwdRemove(callbackTaskId[ind]);
|
||||
if(!callbackRestart)return;
|
||||
semBinaryDestroy(callbackSem[ind]);
|
||||
ringDelete(callbackQ[ind]);
|
||||
epicsRingPointerDelete(callbackQ[ind]);
|
||||
start(ind);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#include "osiThread.h"
|
||||
#include "tsStamp.h"
|
||||
#include "cantProceed.h"
|
||||
#include "osiRing.h"
|
||||
#include "epicsRingPointer.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "dbBase.h"
|
||||
#include "dbStaticLib.h"
|
||||
@@ -77,7 +77,7 @@
|
||||
/* SCAN ONCE */
|
||||
int onceQueueSize = 1000;
|
||||
static semBinaryId onceSem;
|
||||
static ringId onceQ;
|
||||
static epicsRingPointerId onceQ;
|
||||
static threadId onceTaskId;
|
||||
|
||||
/*all other scan types */
|
||||
@@ -442,12 +442,12 @@ void epicsShareAPI scanOnce(void *precord)
|
||||
{
|
||||
static int newOverflow=TRUE;
|
||||
int lockKey;
|
||||
int nput;
|
||||
int pushOK;
|
||||
|
||||
lockKey = interruptLock();
|
||||
nput = ringPut(onceQ,(char *)&precord,sizeof(precord));
|
||||
pushOK = epicsRingPointerPush(onceQ,precord);
|
||||
interruptUnlock(lockKey);
|
||||
if(nput!=sizeof(precord)) {
|
||||
if(!pushOK) {
|
||||
if(newOverflow)errMessage(0,"rngBufPut overflow in scanOnce");
|
||||
newOverflow = FALSE;
|
||||
}else {
|
||||
@@ -464,10 +464,7 @@ static void onceTask(void)
|
||||
if(semBinaryTake(onceSem)!=semTakeOK)
|
||||
errlogPrintf("dbScan: semBinaryTake returned error in onceTask");
|
||||
while(TRUE) {
|
||||
int nbytes = ringGet(onceQ,(void *)&precord,sizeof(precord));
|
||||
if(nbytes==0) break;
|
||||
if(nbytes!=sizeof(precord))
|
||||
errMessage(0,"dbScan: rngBufGet returned error in onceTask");
|
||||
if(!(precord = epicsRingPointerPop(onceQ))) break;
|
||||
dbScanLock(precord);
|
||||
dbProcess(precord);
|
||||
dbScanUnlock(precord);
|
||||
@@ -483,7 +480,7 @@ int epicsShareAPI scanOnceSetQueueSize(int size)
|
||||
|
||||
static void initOnce(void)
|
||||
{
|
||||
if((onceQ = ringCreate(sizeof(void *) * onceQueueSize))==NULL){
|
||||
if((onceQ = epicsRingPointerCreate(onceQueueSize))==NULL){
|
||||
cantProceed("dbScan: initOnce failed");
|
||||
}
|
||||
onceSem=semBinaryMustCreate(semEmpty);
|
||||
|
||||
@@ -12,6 +12,12 @@ SRC_DIRS += $(LIBCOM)/bucketLib
|
||||
INC += bucketLib.h
|
||||
SRCS += bucketLib.c
|
||||
|
||||
SRC_DIRS += $(LIBCOM)/ring
|
||||
#following needed for locating epicsRingPointer.h
|
||||
USR_CFLAGS += -I$(LIBCOM)/ring
|
||||
INC += epicsRingPointer.h
|
||||
SRCS += epicsRingPointer.cpp
|
||||
|
||||
SRC_DIRS += $(LIBCOM)/calc
|
||||
#following needed for locating postfixPvt.h and sCalcPostfixPvt.h
|
||||
USR_CFLAGS += -I$(LIBCOM)/calc
|
||||
@@ -110,8 +116,6 @@ INC += osiSock.h
|
||||
INC += osdSock.h
|
||||
INC += osiInterrupt.h
|
||||
INC += osdInterrupt.h
|
||||
INC += osiRing.h
|
||||
INC += osdRing.h
|
||||
INC += osiSem.h
|
||||
INC += osdSem.h
|
||||
INC += epicsAssert.h
|
||||
@@ -138,7 +142,6 @@ SRCS += osdAssert.c
|
||||
SRCS += osdFindGlobalSymbol.c
|
||||
SRCS += osdInterrupt.c
|
||||
SRCS += osdPoolStatus.c
|
||||
SRCS += osdRing.c
|
||||
SRCS += osdSem.c
|
||||
SRCS += osdThread.c
|
||||
SRCS += osiThread.cpp
|
||||
|
||||
78
src/libCom/ring/epicsRingPointer.cpp
Normal file
78
src/libCom/ring/epicsRingPointer.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*epicsRingPointer.cpp*/
|
||||
/* Author: Marty Kraimer Date: 13OCT2000 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsRingPointer.h"
|
||||
typedef epicsRingPointer<void> voidPointer;
|
||||
|
||||
|
||||
epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size)
|
||||
{
|
||||
voidPointer *pvoidPointer = new voidPointer(size);
|
||||
return(reinterpret_cast<void *>(pvoidPointer));
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
delete pvoidPointer;
|
||||
}
|
||||
|
||||
epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return((void *)(pvoidPointer->pop()));
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id, void *p)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return((pvoidPointer->push(p) ? 1 : 0));
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
pvoidPointer->flush();
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return(pvoidPointer->getFree());
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return(pvoidPointer->getUsed());
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerSize(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return(pvoidPointer->getSize());
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return((pvoidPointer->isEmpty()) ? 1 : 0);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return((pvoidPointer->isFull()) ? 1 : 0);
|
||||
}
|
||||
136
src/libCom/ring/epicsRingPointer.h
Normal file
136
src/libCom/ring/epicsRingPointer.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/*epicsRingPointer.h */
|
||||
|
||||
/* Author: Marty Kraimer Date: 15JUL99 */
|
||||
|
||||
/********************COPYRIGHT NOTIFICATION**********************************
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef INCepicsRingPointerh
|
||||
#define INCepicsRingPointerh
|
||||
|
||||
/* NOTES
|
||||
If there is only one writer it is not necessary to lock push
|
||||
If there is a single reader it is not necessary to lock pop
|
||||
*/
|
||||
|
||||
#include "shareLib.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
template <class T> class epicsRingPointer
|
||||
{
|
||||
public:
|
||||
epicsRingPointer(int size);
|
||||
~epicsRingPointer();
|
||||
bool push(T *p);
|
||||
T* pop();
|
||||
void flush();
|
||||
int getFree() const;
|
||||
int getUsed() const;
|
||||
int getSize() const;
|
||||
bool isEmpty() const;
|
||||
bool isFull() const;
|
||||
private:
|
||||
int nextPush;
|
||||
int nextPop;
|
||||
int size;
|
||||
T **buffer;
|
||||
// copy constructor and assignment operator not allowed
|
||||
epicsRingPointer(const epicsRingPointer &);
|
||||
epicsRingPointer& operator=(const epicsRingPointer &);
|
||||
};
|
||||
#endif /*__cplusplus */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *epicsRingPointerId;
|
||||
|
||||
epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size);
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id);
|
||||
/*ringPointerPush returns (0,1) if p (was not, was) put on ring*/
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id,void *p);
|
||||
/*ringPointerPop returns 0 if ring is empty*/
|
||||
epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) ;
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Following is implementation */
|
||||
/* Algorithm note
|
||||
* Space is allocated for one additional element.
|
||||
* A put request is rejected if the it would cause nextPush to equal nextPop
|
||||
* The algorithm does not require locking puts for a single writer
|
||||
* or locking of gets for a single reader
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
|
||||
template <class T> inline epicsRingPointer<T>::epicsRingPointer(int sz)
|
||||
: nextPush(0), nextPop(0), size(sz+1), buffer(new T* [sz+1]) {}
|
||||
|
||||
template <class T> inline epicsRingPointer<T>::~epicsRingPointer()
|
||||
{delete [] buffer;}
|
||||
|
||||
template <class T> inline bool epicsRingPointer<T>::push(T *p)
|
||||
{
|
||||
int newNext = nextPush +1;
|
||||
if(newNext>=size) newNext=0;
|
||||
if(newNext==nextPop) return(false);
|
||||
buffer[nextPush] = p;
|
||||
nextPush = newNext;
|
||||
return(true);
|
||||
}
|
||||
|
||||
template <class T> inline T* epicsRingPointer<T>::pop()
|
||||
{
|
||||
if(nextPop == nextPush) return(0);
|
||||
T*p = buffer[nextPop];
|
||||
int newNext= nextPop;
|
||||
++newNext;
|
||||
if(newNext >=size) newNext = 0;
|
||||
nextPop = newNext;
|
||||
return(p);
|
||||
}
|
||||
|
||||
template <class T> inline void epicsRingPointer<T>::flush()
|
||||
{ nextPop = nextPush = 0;}
|
||||
|
||||
template <class T> inline int epicsRingPointer<T>::getFree() const
|
||||
{
|
||||
int n = nextPop - nextPush - 1;
|
||||
if (n < 0) n += size;
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T> inline int epicsRingPointer<T>::getUsed() const
|
||||
{
|
||||
int n = nextPush - nextPop;
|
||||
if (n < 0) n += size;
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T> inline int epicsRingPointer<T>::getSize() const
|
||||
{return(size-1);}
|
||||
|
||||
template <class T> inline bool epicsRingPointer<T>::isEmpty() const
|
||||
{return(nextPush==nextPop);}
|
||||
|
||||
template <class T> inline bool epicsRingPointer<T>::isFull() const
|
||||
{
|
||||
int count = nextPush - nextPop +1;
|
||||
return((count == 0) || (count == size));
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* INCepicsRingPointerh */
|
||||
Reference in New Issue
Block a user