Merge ~epics-core/epics-base/+git/ralph:fix-1770292 into ~epics-core/epics-base/+git/epics-base:3.14

Proposed by Ralph Lange
Status: Merged
Approved by: Ralph Lange
Approved revision: 2d9c5e99a191f15ca7d20a8546be922057eb9598
Merge reported by: Ralph Lange
Merged at revision: 2d9c5e99a191f15ca7d20a8546be922057eb9598
Proposed branch: ~epics-core/epics-base/+git/ralph:fix-1770292
Merge into: ~epics-core/epics-base/+git/epics-base:3.14
Diff against target: 57 lines (+12/-12)
3 files modified
src/db/dbAccess.c (+4/-4)
src/rec/longinRecord.c (+4/-4)
src/rec/longoutRecord.c (+4/-4)
Reviewer Review Type Date Requested Status
Andrew Johnson Approve
Ralph Lange Needs Resubmitting
Review via email: mp+345368@code.launchpad.net

Commit message

Fix for LaunchPad Bugs #1770292 and #1771298

Description of the change

Make get_alarm_double() for longin and longout records work the same as all other record types that implement level alarms.

To post a comment you must log in.
Revision history for this message
Ralph Lange (ralph-lange) wrote :

The change only affects integer type records.

Clients that use DBR_GR_<NATIVE> to get at the metadata will see no change on records that do not configure level alarms (as NaN will be converted to 0).

Clients that always use DBR_GR_DOUBLE metadata (like PyEpics) will see consistent behavior between double and integer type records with unconfigured value alarms.

Revision history for this message
Andrew Johnson (anj) wrote :

Where does the NAN get converted to 0? Do we have explicit code for it somewhere, or are we relying on "that's what happens on my machine," and if the latter is there something in the C spec that guarantees it?

Just checking...

Revision history for this message
Andrew Johnson (anj) wrote :

Eric Norum commented (on core-talk I think) that the C99 spec doesn't cover NAN conversions to integer, and looking at the get_alarm() routine in dbAccess.c it looks like we're currently relying on our implementations to handle it.

Sorry, I think this needs more changes.

review: Needs Fixing
Revision history for this message
Ralph Lange (ralph-lange) wrote :

Ok, I see your point, and I am willing to fix this.

But: this is a different issue, and clearly outside the scope of the change I am trying to do with this branch.
The intention (see Bug #1770292) is to handle all record types similarly. The proposed change is below the RSET API, which defines a method get_alarm_double(). My change does the same as all other record types do, and all record types with no level alarms always return NaN. NaN is a valid double and does not break the RSET API.

The problem that you are pointing to has been introduced with the change to use NaN back in 2009. Any client asking for DBR_GR_<integer> has been relying on that undefined conversion behavior, for the last nine years.

I will create a separate issue for the conversion problem, and re-propose this branch, unchanged, after the other fix has been merged.

review: Needs Resubmitting
Revision history for this message
Ralph Lange (ralph-lange) wrote :

As the other fix was trivial, I did add it in this branch.

Please have another look.

review: Needs Resubmitting
Revision history for this message
Andrew Johnson (anj) wrote :

That addition solves the NaN problem for the longin/longout record types, thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c
2index ef27afa..b60594f 100644
3--- a/src/db/dbAccess.c
4+++ b/src/db/dbAccess.c
5@@ -297,10 +297,10 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer,
6 if (*options & DBR_AL_LONG) {
7 struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer;
8
9- pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit;
10- pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit;
11- pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit;
12- pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit;
13+ pal->upper_alarm_limit = isfinite(ald.upper_alarm_limit) ? (epicsInt32) ald.upper_alarm_limit : 0;
14+ pal->upper_warning_limit = isfinite(ald.upper_warning_limit) ? (epicsInt32) ald.upper_warning_limit : 0;
15+ pal->lower_warning_limit = isfinite(ald.lower_warning_limit) ? (epicsInt32) ald.lower_warning_limit : 0;
16+ pal->lower_alarm_limit = isfinite(ald.lower_alarm_limit) ? (epicsInt32) ald.lower_alarm_limit : 0;
17
18 if (no_data)
19 *options ^= DBR_AL_LONG; /*Turn off option*/
20diff --git a/src/rec/longinRecord.c b/src/rec/longinRecord.c
21index 58d9ccf..12da09c 100644
22--- a/src/rec/longinRecord.c
23+++ b/src/rec/longinRecord.c
24@@ -201,10 +201,10 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
25 longinRecord *prec=(longinRecord *)paddr->precord;
26
27 if(paddr->pfield==(void *)&prec->val){
28- pad->upper_alarm_limit = prec->hihi;
29- pad->upper_warning_limit = prec->high;
30- pad->lower_warning_limit = prec->low;
31- pad->lower_alarm_limit = prec->lolo;
32+ pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
33+ pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
34+ pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
35+ pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
36 } else recGblGetAlarmDouble(paddr,pad);
37 return(0);
38 }
39diff --git a/src/rec/longoutRecord.c b/src/rec/longoutRecord.c
40index a57d528..c6ba45a 100644
41--- a/src/rec/longoutRecord.c
42+++ b/src/rec/longoutRecord.c
43@@ -242,10 +242,10 @@ static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
44 int fieldIndex = dbGetFieldIndex(paddr);
45
46 if(fieldIndex == longoutRecordVAL) {
47- pad->upper_alarm_limit = prec->hihi;
48- pad->upper_warning_limit = prec->high;
49- pad->lower_warning_limit = prec->low;
50- pad->lower_alarm_limit = prec->lolo;
51+ pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
52+ pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
53+ pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
54+ pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
55 } else recGblGetAlarmDouble(paddr,pad);
56 return(0);
57 }

Subscribers

People subscribed via source and target branches