Merge remote-tracking branch 'githubbhill/timestamp-before-outlink' into 7.0

* githubbhill/timestamp-before-outlink:
  Update RELEASE_NOTES for timestamp-before-outlink
  Patch record processing routines to update timestamp before processing outlinks
This commit is contained in:
Michael Davidsaver
2020-11-18 10:48:57 -08:00
11 changed files with 98 additions and 18 deletions
+14
View File
@@ -17,6 +17,20 @@ should also be read to understand what has changed since earlier releases.
<!-- Insert new items immediately below here ... -->
### Timestamp before processing output links
The record processing code for records with output links has been modified
to update the timestamp via recGblGetTimeStamp() before processing the
output links. This ensures that other records which get processed via
the output link can use TSEL links to fetch the timestamp which corresponds
to the data processed by the output link.
This change could result in a slightly earlier timestamp for records whose
output link is handled by a device driver, but only if the device driver does
not handle its own timestamping via TSE -2 and instead uses TSE 0 or TSE -1
to get current time or best time, and the time spent in the device driver is
greater than your timestamp provider resolution. For these situations it is
recommended to set TSE to -2 and set the timestamp in the driver code.
### Add registerAllRecordDeviceDrivers()
Addition of registerAllRecordDeviceDrivers() as an iocsh function
+1 -1
View File
@@ -227,6 +227,7 @@ static long process(struct dbCommon *pcommon)
return 0;
prec->pact = TRUE;
recGblGetTimeStamp(prec);
/* Push the output link values */
if (!status) {
@@ -237,7 +238,6 @@ static long process(struct dbCommon *pcommon)
(&prec->neva)[i]);
}
recGblGetTimeStamp(prec);
monitor(prec);
recGblFwdLink(prec);
prec->pact = FALSE;
+12 -2
View File
@@ -158,12 +158,22 @@ static long process(struct dbCommon *pcommon)
return S_dev_missingSup;
}
if ( !pact ) {
prec->udf = FALSE;
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
status = writeValue(prec); /* write the data */
if (!pact && prec->pact) return 0;
prec->pact = TRUE;
prec->udf = FALSE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
monitor(prec);
/* process the forward scan link record */
+8 -2
View File
@@ -82,7 +82,7 @@ rset aoRSET={
put_enum_str,
get_graphic_double,
get_control_double,
get_alarm_double
get_alarm_double
};
epicsExportAddress(rset,aoRSET);
@@ -187,6 +187,9 @@ static long process(struct dbCommon *pcommon)
}
if(!status) convert(prec, value);
prec->udf = isnan(prec->val);
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check for alarms */
@@ -220,7 +223,10 @@ static long process(struct dbCommon *pcommon)
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check event list */
monitor(prec);
+9 -2
View File
@@ -155,7 +155,7 @@ static long init_record(struct dbCommon *pcommon,int pass)
pcallback->precord = (struct dbCommon *) prec;
if (pdset->common.init_record) {
status=(*pdset->common.init_record)(pcommon);
status=(*pdset->common.init_record)(pcommon);
if(status==0) {
if(prec->rval==0) prec->val = 0;
else prec->val = 1;
@@ -209,6 +209,10 @@ static long process(struct dbCommon *pcommon)
if(prec->val==0) prec->rval = 0;
else prec->rval = prec->mask;
} else prec->rval = (epicsUInt32)prec->val;
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check for alarms */
@@ -245,7 +249,10 @@ static long process(struct dbCommon *pcommon)
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
if((prec->val==1) && (prec->high>0)){
myCallback *pcallback;
+10 -4
View File
@@ -226,6 +226,7 @@ static long process(struct dbCommon *pcommon)
struct calcoutRecord *prec = (struct calcoutRecord *)pcommon;
rpvtStruct *prpvt = prec->rpvt;
int doOutput;
unsigned char pact=prec->pact;
if (!prec->pact) {
prec->pact = TRUE;
@@ -241,6 +242,12 @@ static long process(struct dbCommon *pcommon)
}
}
checkAlarms(prec);
if ( !pact ) {
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStamp(prec);
}
/* check for output link execution */
switch (prec->oopt) {
case calcoutOOPT_Every_Time:
@@ -269,7 +276,6 @@ static long process(struct dbCommon *pcommon)
if (doOutput) {
if (prec->odly > 0.0) {
prec->dlya = 1;
recGblGetTimeStamp(prec);
db_post_events(prec, &prec->dlya, DBE_VALUE);
callbackRequestProcessCallbackDelayed(&prpvt->doOutCb,
prec->prio, prec, (double)prec->odly);
@@ -281,11 +287,12 @@ static long process(struct dbCommon *pcommon)
prec->pact = TRUE;
}
}
recGblGetTimeStamp(prec);
} else { /* pact == TRUE */
/* Update timestamp again for asynchronous devices */
recGblGetTimeStamp(prec);
if (prec->dlya) {
prec->dlya = 0;
recGblGetTimeStamp(prec);
db_post_events(prec, &prec->dlya, DBE_VALUE);
/* Make pact FALSE for asynchronous device support*/
prec->pact = FALSE;
@@ -294,7 +301,6 @@ static long process(struct dbCommon *pcommon)
prec->pact = TRUE;
} else {/*Device Support is asynchronous*/
writeValue(prec);
recGblGetTimeStamp(prec);
}
}
monitor(prec);
+10 -3
View File
@@ -111,7 +111,7 @@ static long init_record(dbCommon *pcommon, int pass)
prec->udf=FALSE;
}
if (pdset->common.init_record) {
if ((status = pdset->common.init_record(pcommon))) return status;
if ((status = pdset->common.init_record(pcommon))) return status;
}
prec->mlst = prec->val;
prec->alst = prec->val;
@@ -122,7 +122,7 @@ static long init_record(dbCommon *pcommon, int pass)
static long process(dbCommon *pcommon)
{
int64outRecord *prec = (int64outRecord*)pcommon;
int64outdset *pdset = (int64outdset *)(prec->dset);
int64outdset *pdset = (int64outdset *)(prec->dset);
long status=0;
epicsInt64 value;
unsigned char pact=prec->pact;
@@ -144,6 +144,10 @@ static long process(dbCommon *pcommon)
value = prec->val;
}
if (!status) convert(prec,value);
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check for alarms */
@@ -175,7 +179,10 @@ static long process(dbCommon *pcommon)
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check event list */
monitor(prec);
+8 -1
View File
@@ -146,6 +146,10 @@ static long process(struct dbCommon *pcommon)
value = prec->val;
}
if (!status) convert(prec,value);
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check for alarms */
@@ -177,7 +181,10 @@ static long process(struct dbCommon *pcommon)
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
/* check event list */
monitor(prec);
@@ -194,6 +194,10 @@ static long process(struct dbCommon *pcommon)
prec->udf = FALSE;
/* Convert VAL to RVAL */
convert(prec);
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
CONTINUE:
@@ -224,7 +228,11 @@ CONTINUE:
return 0;
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
monitor(prec);
+9 -1
View File
@@ -215,6 +215,10 @@ static long process(struct dbCommon *pcommon)
prec->udf = FALSE;
/* Convert VAL to RVAL */
convert(prec);
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
CONTINUE:
@@ -248,7 +252,11 @@ CONTINUE:
return 0;
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
monitor(prec);
@@ -147,6 +147,10 @@ static long process(struct dbCommon *pcommon)
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
}
/* Update the timestamp before writing output values so it
* will be uptodate if any downstream records fetch it via TSEL */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if (prec->nsev < INVALID_ALARM )
status=writeValue(prec); /* write the new value */
else {
@@ -173,7 +177,10 @@ static long process(struct dbCommon *pcommon)
if ( !pact && prec->pact ) return(0);
prec->pact = TRUE;
recGblGetTimeStampSimm(prec, prec->simm, NULL);
if ( pact ) {
/* Update timestamp again for asynchronous devices */
recGblGetTimeStampSimm(prec, prec->simm, NULL);
}
monitor(prec);
recGblFwdLink(prec);