Merge 3.16 branch into 7.0
This commit is contained in:
@@ -601,12 +601,12 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
|
||||
macPushScope(handle);
|
||||
macInstallMacros(handle, defines);
|
||||
|
||||
wasOkToBlock = epicsThreadIsOkToBlock();
|
||||
epicsThreadSetOkToBlock(1);
|
||||
|
||||
/*
|
||||
* Read commands till EOF or exit
|
||||
*/
|
||||
argc = 0;
|
||||
wasOkToBlock = epicsThreadIsOkToBlock();
|
||||
epicsThreadSetOkToBlock(1);
|
||||
for (;;) {
|
||||
/*
|
||||
* Read a line
|
||||
@@ -681,15 +681,15 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
|
||||
redirect = NULL;
|
||||
for (;;) {
|
||||
if (argc >= argvCapacity) {
|
||||
char **av;
|
||||
argvCapacity += 50;
|
||||
av = (char **)realloc (argv, argvCapacity * sizeof *argv);
|
||||
if (av == NULL) {
|
||||
int newCapacity = argvCapacity + 20;
|
||||
char **newv = (char **)realloc (argv, newCapacity * sizeof *argv);
|
||||
if (newv == NULL) {
|
||||
fprintf (epicsGetStderr(), "Out of memory!\n");
|
||||
argc = -1;
|
||||
break;
|
||||
}
|
||||
argv = av;
|
||||
argv = newv;
|
||||
argvCapacity = newCapacity;
|
||||
}
|
||||
c = line[icin++];
|
||||
if (c == '\0')
|
||||
@@ -838,16 +838,14 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
|
||||
break;
|
||||
}
|
||||
if (iarg >= argBufCapacity) {
|
||||
void *np;
|
||||
|
||||
argBufCapacity += 20;
|
||||
np = realloc (argBuf, argBufCapacity * sizeof *argBuf);
|
||||
if (np == NULL) {
|
||||
int newCapacity = argBufCapacity + 20;
|
||||
void *newBuf = realloc(argBuf, newCapacity * sizeof *argBuf);
|
||||
if (newBuf == NULL) {
|
||||
fprintf (epicsGetStderr(), "Out of memory!\n");
|
||||
argBufCapacity -= 20;
|
||||
break;
|
||||
}
|
||||
argBuf = (iocshArgBuf *)np;
|
||||
argBuf = (iocshArgBuf *) newBuf;
|
||||
argBufCapacity = newCapacity;
|
||||
}
|
||||
if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) {
|
||||
argBuf[iarg].aval.ac = argc-iarg;
|
||||
@@ -892,7 +890,7 @@ iocshBody (const char *pathname, const char *commandLine, const char *macros)
|
||||
errlogFlush();
|
||||
if (readlineContext)
|
||||
epicsReadlineEnd(readlineContext);
|
||||
epicsThreadSetOkToBlock( wasOkToBlock);
|
||||
epicsThreadSetOkToBlock(wasOkToBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -236,6 +236,7 @@ static const iocshFuncDef errlogFuncDef = {"errlog",1,errlogArgs};
|
||||
static void errlogCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
errlog(args[0].sval);
|
||||
errlogFlush();
|
||||
}
|
||||
|
||||
/* iocLogPrefix */
|
||||
|
||||
@@ -225,14 +225,14 @@ static int generalTimeGetEventPriority(epicsTimeStamp *pDest, int eventNumber,
|
||||
gtProvider *ptp;
|
||||
int status = S_time_noProvider;
|
||||
epicsTimeStamp ts;
|
||||
STATIC_ASSERT ( epicsTimeEventBestTime == -1 );
|
||||
|
||||
generalTime_Init();
|
||||
|
||||
IFDEBUG(2)
|
||||
printf("generalTimeGetEventPriority(eventNum=%d)\n", eventNumber);
|
||||
|
||||
if ((eventNumber < 0 || eventNumber >= NUM_TIME_EVENTS) &&
|
||||
(eventNumber != epicsTimeEventBestTime))
|
||||
if (eventNumber < epicsTimeEventBestTime)
|
||||
return S_time_badEvent;
|
||||
|
||||
epicsMutexMustLock(gtPvt.eventListLock);
|
||||
@@ -245,7 +245,9 @@ static int generalTimeGetEventPriority(epicsTimeStamp *pDest, int eventNumber,
|
||||
if (pPrio)
|
||||
*pPrio = ptp->priority;
|
||||
|
||||
if (eventNumber == epicsTimeEventBestTime) {
|
||||
if (eventNumber >= NUM_TIME_EVENTS) {
|
||||
*pDest = ts;
|
||||
} else if (eventNumber == epicsTimeEventBestTime) {
|
||||
if (epicsTimeGreaterThanEqual(&ts,
|
||||
>Pvt.lastProvidedBestTime)) {
|
||||
*pDest = ts;
|
||||
|
||||
@@ -17,7 +17,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define NUM_TIME_EVENTS 256
|
||||
/* Time Events are numbered 0 through (NUM_TIME_EVENTS-1) */
|
||||
/* Time Events numbered 0 through (NUM_TIME_EVENTS-1) are validated by */
|
||||
/* code in epicsGeneralTime.c that tests for advancing timestamps and */
|
||||
/* enforces that restriction. Event numbers greater than or equal to */
|
||||
/* NUM_TIME_EVENTS are now allowed if supported by a custom time provider */
|
||||
/* which should provide its own advancing timestamp validation. */
|
||||
|
||||
epicsShareFunc void generalTime_Init(void);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ typedef struct ringPvt {
|
||||
volatile int nextPut;
|
||||
volatile int nextGet;
|
||||
int size;
|
||||
int highWaterMark;
|
||||
volatile char buffer[1]; /* actually larger */
|
||||
}ringPvt;
|
||||
|
||||
@@ -47,6 +48,7 @@ epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size)
|
||||
if(!pring)
|
||||
return NULL;
|
||||
pring->size = size + SLOP;
|
||||
pring->highWaterMark = 0;
|
||||
pring->nextGet = 0;
|
||||
pring->nextPut = 0;
|
||||
pring->lock = 0;
|
||||
@@ -118,7 +120,7 @@ epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
int nextGet, nextPut, size;
|
||||
int freeCount, copyCount, topCount;
|
||||
int freeCount, copyCount, topCount, used;
|
||||
|
||||
if (pring->lock) epicsSpinLock(pring->lock);
|
||||
nextGet = pring->nextGet;
|
||||
@@ -131,8 +133,9 @@ epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
if (pring->lock) epicsSpinUnlock(pring->lock);
|
||||
return 0;
|
||||
}
|
||||
if (nbytes)
|
||||
if (nbytes) {
|
||||
memcpy ((void *)&pring->buffer[nextPut], value, nbytes);
|
||||
}
|
||||
nextPut += nbytes;
|
||||
}
|
||||
else {
|
||||
@@ -143,8 +146,9 @@ epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
}
|
||||
topCount = size - nextPut;
|
||||
copyCount = (nbytes > topCount) ? topCount : nbytes;
|
||||
if (copyCount)
|
||||
if (copyCount) {
|
||||
memcpy ((void *)&pring->buffer[nextPut], value, copyCount);
|
||||
}
|
||||
nextPut += copyCount;
|
||||
if (nextPut == size) {
|
||||
int nLeft = nbytes - copyCount;
|
||||
@@ -155,6 +159,10 @@ epicsShareFunc int epicsShareAPI epicsRingBytesPut(
|
||||
}
|
||||
pring->nextPut = nextPut;
|
||||
|
||||
used = nextPut - nextGet;
|
||||
if (used < 0) used += pring->size;
|
||||
if (used > pring->highWaterMark) pring->highWaterMark = used;
|
||||
|
||||
if (pring->lock) epicsSpinUnlock(pring->lock);
|
||||
return nbytes;
|
||||
}
|
||||
@@ -224,3 +232,20 @@ epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id)
|
||||
{
|
||||
return (epicsRingBytesFreeBytes(id) <= 0);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesHighWaterMark(epicsRingBytesIdConst id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
return pring->highWaterMark;
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesResetHighWaterMark(epicsRingBytesId id)
|
||||
{
|
||||
ringPvt *pring = (ringPvt *)id;
|
||||
int used;
|
||||
if (pring->lock) epicsSpinLock(pring->lock);
|
||||
used = pring->nextGet - pring->nextPut;
|
||||
if (used < 0) used += pring->size;
|
||||
pring->highWaterMark = used;
|
||||
if (pring->lock) epicsSpinUnlock(pring->lock);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
#include "shareLib.h"
|
||||
|
||||
typedef void *epicsRingBytesId;
|
||||
typedef void const *epicsRingBytesIdConst;
|
||||
|
||||
epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int nbytes);
|
||||
/* Same, but secured by a spinlock */
|
||||
@@ -39,6 +40,8 @@ epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingBytesHighWaterMark(epicsRingBytesIdConst id);
|
||||
epicsShareFunc void epicsShareAPI epicsRingBytesResetHighWaterMark(epicsRingBytesId id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -90,3 +90,15 @@ epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id)
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
return((pvoidPointer->isFull()) ? 1 : 0);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetHighWaterMark(epicsRingPointerIdConst id)
|
||||
{
|
||||
voidPointer const *pvoidPointer = reinterpret_cast<voidPointer const*>(id);
|
||||
return(pvoidPointer->getHighWaterMark());
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerResetHighWaterMark(epicsRingPointerId id)
|
||||
{
|
||||
voidPointer *pvoidPointer = reinterpret_cast<voidPointer*>(id);
|
||||
pvoidPointer->resetHighWaterMark();
|
||||
}
|
||||
|
||||
@@ -40,18 +40,22 @@ public: /* Functions */
|
||||
int getSize() const;
|
||||
bool isEmpty() const;
|
||||
bool isFull() const;
|
||||
int getHighWaterMark() const;
|
||||
void resetHighWaterMark();
|
||||
|
||||
private: /* Prevent compiler-generated member functions */
|
||||
/* default constructor, copy constructor, assignment operator */
|
||||
epicsRingPointer();
|
||||
epicsRingPointer(const epicsRingPointer &);
|
||||
epicsRingPointer& operator=(const epicsRingPointer &);
|
||||
int getUsedNoLock() const;
|
||||
|
||||
private: /* Data */
|
||||
epicsSpinId lock;
|
||||
volatile int nextPush;
|
||||
volatile int nextPop;
|
||||
int size;
|
||||
int highWaterMark;
|
||||
T * volatile * buffer;
|
||||
};
|
||||
|
||||
@@ -59,6 +63,7 @@ extern "C" {
|
||||
#endif /*__cplusplus */
|
||||
|
||||
typedef void *epicsRingPointerId;
|
||||
typedef void const *epicsRingPointerIdConst;
|
||||
|
||||
epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size);
|
||||
/* Same, but secured by a spinlock */
|
||||
@@ -74,6 +79,8 @@ epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id)
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id);
|
||||
epicsShareFunc int epicsShareAPI epicsRingPointerGetHighWaterMark(epicsRingPointerIdConst id);
|
||||
epicsShareFunc void epicsShareAPI epicsRingPointerResetHighWaterMark(epicsRingPointerId id);
|
||||
|
||||
/* This routine was incorrectly named in previous releases */
|
||||
#define epicsRingPointerSize epicsRingPointerGetSize
|
||||
@@ -95,7 +102,8 @@ epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id);
|
||||
|
||||
template <class T>
|
||||
inline epicsRingPointer<T>::epicsRingPointer(int sz, bool locked) :
|
||||
lock(0), nextPush(0), nextPop(0), size(sz+1), buffer(new T* [sz+1])
|
||||
lock(0), nextPush(0), nextPop(0), size(sz+1), highWaterMark(0),
|
||||
buffer(new T* [sz+1])
|
||||
{
|
||||
if (locked)
|
||||
lock = epicsSpinCreate();
|
||||
@@ -121,6 +129,8 @@ inline bool epicsRingPointer<T>::push(T *p)
|
||||
}
|
||||
buffer[next] = p;
|
||||
nextPush = newNext;
|
||||
int used = getUsedNoLock();
|
||||
if (used > highWaterMark) highWaterMark = used;
|
||||
if (lock) epicsSpinUnlock(lock);
|
||||
return(true);
|
||||
}
|
||||
@@ -161,12 +171,19 @@ inline int epicsRingPointer<T>::getFree() const
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int epicsRingPointer<T>::getUsedNoLock() const
|
||||
{
|
||||
int n = nextPush - nextPop;
|
||||
if (n < 0) n += size;
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int epicsRingPointer<T>::getUsed() const
|
||||
{
|
||||
if (lock) epicsSpinLock(lock);
|
||||
int n = nextPush - nextPop;
|
||||
if (n < 0) n += size;
|
||||
int n = getUsedNoLock();
|
||||
if (lock) epicsSpinUnlock(lock);
|
||||
return n;
|
||||
}
|
||||
@@ -196,6 +213,20 @@ inline bool epicsRingPointer<T>::isFull() const
|
||||
return((count == 0) || (count == size));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline int epicsRingPointer<T>::getHighWaterMark() const
|
||||
{
|
||||
return highWaterMark;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void epicsRingPointer<T>::resetHighWaterMark()
|
||||
{
|
||||
if (lock) epicsSpinLock(lock);
|
||||
highWaterMark = getUsedNoLock();
|
||||
if (lock) epicsSpinUnlock(lock);
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* INCepicsRingPointerh */
|
||||
|
||||
Reference in New Issue
Block a user