Merged changes from 3.15 branch, to revno 12807

This commit is contained in:
Andrew Johnson
2017-02-01 11:57:04 -06:00
90 changed files with 1401 additions and 959 deletions

View File

@@ -109,6 +109,7 @@ int main(int argc,char **argv)
pmynode[npv] = callocMustSucceed(1, sizeof(MYNODE), "caMonitor");
npv++;
}
fclose(fp);
SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create");
SEVCHK(ca_add_exception_event(exceptionCallback,NULL),
"ca_add_exception_event");

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
@@ -30,23 +29,23 @@ exAsyncPV::exAsyncPV ( exServer & cas, pvInfo & setup,
//
caStatus exAsyncPV::read (const casCtx &ctx, gdd &valueIn)
{
exAsyncReadIO *pIO;
if ( this->simultAsychReadIOCount >= this->cas.maxSimultAsyncIO () ) {
return S_casApp_postponeAsyncIO;
}
exAsyncReadIO *pIO;
pIO = new exAsyncReadIO ( this->cas, ctx,
*this, valueIn, this->asyncDelay );
if ( ! pIO ) {
if ( this->simultAsychReadIOCount >= this->cas.maxSimultAsyncIO () ) {
return S_casApp_postponeAsyncIO;
}
pIO = new exAsyncReadIO ( this->cas, ctx,
*this, valueIn, this->asyncDelay );
if ( ! pIO ) {
if ( this->simultAsychReadIOCount > 0 ) {
return S_casApp_postponeAsyncIO;
}
else {
return S_casApp_noMemory;
return S_casApp_noMemory;
}
}
this->simultAsychReadIOCount++;
}
this->simultAsychReadIOCount++;
return S_casApp_asyncCompletion;
}
@@ -54,24 +53,24 @@ caStatus exAsyncPV::read (const casCtx &ctx, gdd &valueIn)
// exAsyncPV::writeNotify()
//
caStatus exAsyncPV::writeNotify ( const casCtx &ctx, const gdd &valueIn )
{
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
return S_casApp_postponeAsyncIO;
}
{
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
return S_casApp_postponeAsyncIO;
}
exAsyncWriteIO * pIO = new
exAsyncWriteIO * pIO = new
exAsyncWriteIO ( this->cas, ctx, *this,
valueIn, this->asyncDelay );
if ( ! pIO ) {
valueIn, this->asyncDelay );
if ( ! pIO ) {
if ( this->simultAsychReadIOCount > 0 ) {
return S_casApp_postponeAsyncIO;
}
else {
return S_casApp_noMemory;
return S_casApp_noMemory;
}
}
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
}
//
@@ -79,24 +78,24 @@ caStatus exAsyncPV::writeNotify ( const casCtx &ctx, const gdd &valueIn )
//
caStatus exAsyncPV::write ( const casCtx &ctx, const gdd &valueIn )
{
// implement the discard intermediate values, but last value
// implement the discard intermediate values, but last value
// sent always applied behavior that IOCs provide excepting
// that we will alow N requests to pend instead of a limit
// of only one imposed in the IOC
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) {
pStandbyValue.set ( & valueIn );
return S_casApp_success;
}
exAsyncWriteIO * pIO = new
exAsyncWriteIO ( this->cas, ctx, *this,
valueIn, this->asyncDelay );
if ( ! pIO ) {
pStandbyValue.set ( & valueIn );
return S_casApp_success;
return S_casApp_success;
}
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
exAsyncWriteIO * pIO = new
exAsyncWriteIO ( this->cas, ctx, *this,
valueIn, this->asyncDelay );
if ( ! pIO ) {
pStandbyValue.set ( & valueIn );
return S_casApp_success;
}
this->simultAsychWriteIOCount++;
return S_casApp_asyncCompletion;
}
// Implementing a specialized update for exAsyncPV
@@ -150,7 +149,7 @@ void exAsyncPV::removeWriteIO ()
exAsyncWriteIO::exAsyncWriteIO ( exServer & cas,
const casCtx & ctxIn, exAsyncPV & pvIn,
const gdd & valueIn, double asyncDelay ) :
casAsyncWriteIO ( ctxIn ), pv ( pvIn ),
casAsyncWriteIO ( ctxIn ), pv ( pvIn ),
timer ( cas.createTimer () ), pValue(valueIn)
{
this->timer.start ( *this, asyncDelay );
@@ -168,7 +167,7 @@ exAsyncWriteIO::~exAsyncWriteIO()
if ( this->pValue.valid () ) {
this->pv.updateFromAsyncWrite ( *this->pValue );
}
this->pv.removeWriteIO();
this->pv.removeWriteIO();
}
//
@@ -179,9 +178,9 @@ epicsTimerNotify::expireStatus exAsyncWriteIO::
expire ( const epicsTime & /* currentTime */ )
{
assert ( this->pValue.valid () );
caStatus status = this->pv.updateFromAsyncWrite ( *this->pValue );
this->pValue.set ( 0 );
this->postIOCompletion ( status );
caStatus status = this->pv.updateFromAsyncWrite ( *this->pValue );
this->pValue.set ( 0 );
this->postIOCompletion ( status );
return noRestart;
}
@@ -191,7 +190,7 @@ epicsTimerNotify::expireStatus exAsyncWriteIO::
exAsyncReadIO::exAsyncReadIO ( exServer & cas, const casCtx & ctxIn,
exAsyncPV & pvIn, gdd & protoIn,
double asyncDelay ) :
casAsyncReadIO ( ctxIn ), pv ( pvIn ),
casAsyncReadIO ( ctxIn ), pv ( pvIn ),
timer ( cas.createTimer() ), pProto ( protoIn )
{
this->timer.start ( *this, asyncDelay );
@@ -202,7 +201,7 @@ exAsyncReadIO::exAsyncReadIO ( exServer & cas, const casCtx & ctxIn,
//
exAsyncReadIO::~exAsyncReadIO()
{
this->pv.removeReadIO ();
this->pv.removeReadIO ();
this->timer.destroy ();
}
@@ -213,16 +212,16 @@ exAsyncReadIO::~exAsyncReadIO()
epicsTimerNotify::expireStatus
exAsyncReadIO::expire ( const epicsTime & /* currentTime */ )
{
//
// map between the prototype in and the
// current value
//
caStatus status = this->pv.exPV::readNoCtx ( this->pProto );
//
// map between the prototype in and the
// current value
//
caStatus status = this->pv.exPV::readNoCtx ( this->pProto );
//
// post IO completion
//
this->postIOCompletion ( status, *this->pProto );
//
// post IO completion
//
this->postIOCompletion ( status, *this->pProto );
return noRestart;
}

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
@@ -42,7 +41,7 @@ exPV::exPV ( exServer & casIn, pvInfo & setup,
//
// no dataless PV allowed
//
assert (this->info.getElementCount()>=1u);
assert (this->info.getCapacity()>=1u);
//
// start a very slow background scan

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// fileDescriptorManager.process(delay);
@@ -304,7 +303,7 @@ exPV *pvInfo::createPV ( exServer & cas, bool preCreateFlag,
// depending on the io type and the number
// of elements
//
if (this->elementCount==1u) {
if (this->capacity==1u) {
switch (this->ioType){
case excasIoSync:
pNewPV = new exScalarPV ( cas, *this, preCreateFlag, scanOn );

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
//
// Example EPICS CA server
@@ -76,8 +75,10 @@ public:
double getLopr () const;
aitEnum getType () const;
excasIoType getIOType () const;
unsigned getElementCount () const;
void unlinkPV ();
unsigned getCapacity () const;
unsigned getElementCount () const;
void setElementCount (unsigned);
void unlinkPV ();
exPV *createPV ( exServer & exCAS, bool preCreateFlag,
bool scanOn, double asyncDelay );
void deletePV ();
@@ -88,7 +89,8 @@ private:
const double lopr;
aitEnum type;
const excasIoType ioType;
const unsigned elementCount;
const unsigned capacity;
unsigned elementCount;
exPV * pPV;
pvInfo & operator = ( const pvInfo & );
};
@@ -441,8 +443,8 @@ inline pvInfo::pvInfo ( double scanPeriodIn, const char *pNameIn,
scanPeriod ( scanPeriodIn ), pName ( pNameIn ),
hopr ( hoprIn ), lopr ( loprIn ), type ( typeIn ),
ioType ( ioTypeIn ), elementCount ( countIn ),
pPV ( 0 )
ioType ( ioTypeIn ), capacity ( countIn ),
elementCount ( 0 ), pPV ( 0 )
{
}
@@ -454,8 +456,8 @@ inline pvInfo::pvInfo ( const pvInfo & copyIn ) :
scanPeriod ( copyIn.scanPeriod ), pName ( copyIn.pName ),
hopr ( copyIn.hopr ), lopr ( copyIn.lopr ), type ( copyIn.type ),
ioType ( copyIn.ioType ), elementCount ( copyIn.elementCount ),
pPV ( copyIn.pPV )
ioType ( copyIn.ioType ), capacity ( copyIn.capacity ),
elementCount ( copyIn.elementCount ), pPV ( copyIn.pPV )
{
}
@@ -509,12 +511,22 @@ inline excasIoType pvInfo::getIOType () const
return this->ioType;
}
inline unsigned pvInfo::getElementCount () const
{
return this->elementCount;
inline unsigned pvInfo::getCapacity () const
{
return this->capacity;
}
inline void pvInfo::unlinkPV ()
inline unsigned pvInfo::getElementCount () const
{
return this->elementCount;
}
inline void pvInfo::setElementCount (unsigned newCount)
{
this->elementCount = newCount;
}
inline void pvInfo::unlinkPV ()
{
this->pPV = NULL;
}

View File

@@ -3,9 +3,8 @@
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
#include "exServer.h"
@@ -48,7 +47,7 @@ unsigned exVectorPV::maxDimension() const
aitIndex exVectorPV::maxBound (unsigned dimension) const
{
if (dimension==0u) {
return this->info.getElementCount();
return this->info.getCapacity();
}
else {
return 0u;
@@ -60,45 +59,40 @@ aitIndex exVectorPV::maxBound (unsigned dimension) const
//
void exVectorPV::scan()
{
caStatus status;
double radians;
smartGDDPointer pDD;
aitFloat32 *pF, *pFE;
const aitFloat32 *pCF;
float newValue;
float limit;
exVecDestructor *pDest;
int gddStatus;
static epicsTime startTime = epicsTime::getCurrent();
//
// update current time (so we are not required to do
// this every time that we write the PV which impacts
// throughput under sunos4 because gettimeofday() is
// slow)
// update current time
//
this->currentTime = epicsTime::getCurrent();
pDD = new gddAtomic (gddAppType_value, aitEnumFloat64,
1u, this->info.getElementCount());
// demonstrate a changing array size
unsigned ramp = 15 & (unsigned) (this->currentTime - startTime);
unsigned newSize = this->info.getCapacity();
if (newSize > ramp) {
newSize -= ramp;
}
smartGDDPointer pDD = new gddAtomic (gddAppType_value, aitEnumFloat64,
1u, newSize);
if ( ! pDD.valid () ) {
return;
}
//
// smart pointer class manages reference count after this point
//
gddStatus = pDD->unreference();
assert (!gddStatus);
gddStatus gdds = pDD->unreference();
assert(!gdds);
//
// allocate array buffer
//
pF = new aitFloat32 [this->info.getElementCount()];
aitFloat64 * pF = new aitFloat64 [newSize];
if (!pF) {
return;
}
pDest = new exVecDestructor;
exVecDestructor * pDest = new exVecDestructor;
if (!pDest) {
delete [] pF;
return;
@@ -114,37 +108,39 @@ void exVectorPV::scan()
// double check for reasonable bounds on the
// current value
//
pCF=NULL;
if ( this->pValue.valid () ) {
if (this->pValue->dimension()==1u) {
const gddBounds *pB = this->pValue->getBounds();
if (pB[0u].size()==this->info.getElementCount()) {
pCF = *this->pValue;
}
}
const aitFloat64 *pCF = NULL, *pCFE = NULL;
if (this->pValue.valid () &&
this->pValue->dimension() == 1u) {
const gddBounds *pB = this->pValue->getBounds();
pCF = *this->pValue;
pCFE = &pCF[pB->size()];
}
pFE = &pF[this->info.getElementCount()];
while (pF<pFE) {
radians = (rand () * 2.0 * myPI)/RAND_MAX;
if (pCF) {
aitFloat64 * pFE = &pF[newSize];
while (pF < pFE) {
double radians = (rand () * 2.0 * myPI)/RAND_MAX;
double newValue;
if (pCF && pCF < pCFE) {
newValue = *pCF++;
}
else {
newValue = 0.0f;
}
newValue += (float) (sin (radians) / 10.0);
limit = (float) this->info.getHopr();
newValue += (sin (radians) / 10.0);
double limit = this->info.getHopr();
newValue = epicsMin (newValue, limit);
limit = (float) this->info.getLopr();
limit = this->info.getLopr();
newValue = epicsMax (newValue, limit);
*(pF++) = newValue;
*pF++ = newValue;
}
aitTimeStamp gddts = this->currentTime;
pDD->setTimeStamp ( & gddts );
status = this->update ( *pDD );
caStatus status = this->update ( *pDD );
this->info.setElementCount(newSize);
if ( status != S_casApp_success ) {
errMessage (status, "vector scan update failed\n");
}
@@ -166,7 +162,7 @@ void exVectorPV::scan()
//
caStatus exVectorPV::updateValue ( const gdd & value )
{
aitUint32 newSize = 0;
//
// Check bounds of incoming request
// (and see if we are replacing all elements -
@@ -183,7 +179,9 @@ caStatus exVectorPV::updateValue ( const gdd & value )
if ( pb[0u].first() != 0u ) {
return S_casApp_outOfBounds;
}
else if ( pb[0u].size() > this->info.getElementCount() ) {
newSize = pb[0u].size();
if ( newSize > this->info.getCapacity() ) {
return S_casApp_outOfBounds;
}
}
@@ -193,14 +191,14 @@ caStatus exVectorPV::updateValue ( const gdd & value )
//
return S_casApp_outOfBounds;
}
//
// Create a new array data descriptor
// (so that old values that may be referenced on the
// event queue are not replaced)
//
smartGDDPointer pNewValue ( new gddAtomic ( gddAppType_value, aitEnumFloat64,
1u, this->info.getElementCount() ) );
smartGDDPointer pNewValue ( new gddAtomic ( gddAppType_value, aitEnumFloat64,
1u, newSize ) );
if ( ! pNewValue.valid() ) {
return S_casApp_noMemory;
}
@@ -211,21 +209,20 @@ caStatus exVectorPV::updateValue ( const gdd & value )
//
gddStatus gdds = pNewValue->unreference( );
assert ( ! gdds );
//
// allocate array buffer
//
aitFloat64 * pF = new aitFloat64 [this->info.getElementCount()];
aitFloat64 * pF = new aitFloat64 [newSize];
if (!pF) {
return S_casApp_noMemory;
}
//
// Install (and initialize) array buffer
// if no old values exist
//
unsigned count = this->info.getElementCount();
for ( unsigned i = 0u; i < count; i++ ) {
for ( unsigned i = 0u; i < newSize; i++ ) {
pF[i] = 0.0f;
}
@@ -240,7 +237,7 @@ caStatus exVectorPV::updateValue ( const gdd & value )
// (do this before we increment pF)
//
pNewValue->putRef ( pF, pDest );
//
// copy in the values that they are writing
//
@@ -248,9 +245,10 @@ caStatus exVectorPV::updateValue ( const gdd & value )
if ( gdds ) {
return S_cas_noConvert;
}
this->pValue = pNewValue;
this->info.setElementCount(newSize);
return S_casApp_success;
}
@@ -261,6 +259,6 @@ caStatus exVectorPV::updateValue ( const gdd & value )
//
void exVecDestructor::run ( void *pUntyped )
{
aitFloat32 * pf = reinterpret_cast < aitFloat32 * > ( pUntyped );
aitFloat64 * pf = reinterpret_cast < aitFloat64 * > ( pUntyped );
delete [] pf;
}

View File

@@ -34,3 +34,10 @@ CHECK_RELEASE = YES
# or CROSS_OPT settings from base/configure/CONFIG_SITE
#HOST_OPT = NO
#CROSS_OPT = NO
# These allow developers to override the CONFIG_SITE variable
# settings without having to modify the configure/CONFIG_SITE
# file itself.
-include $(TOP)/../CONFIG_SITE.local
-include $(TOP)/configure/CONFIG_SITE.local

View File

@@ -35,3 +35,9 @@ EPICS_BASE = _EPICS_BASE_
# Set RULES here if you want to use build rules from somewhere
# other than EPICS_BASE:
#RULES = $(MODULES)/build-rules
# These allow developers to override the RELEASE variable settings
# without having to modify the configure/RELEASE file itself.
-include $(TOP)/../RELEASE.local
-include $(TOP)/configure/RELEASE.local