int64in only checks lower 32 bits for change
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
EPICS Base |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
Create an int64in record and write these values
(example uses bash to convert hex into decimal since caput cannot directly handle hex?):
caput sixtyfour $(( 16#FF ))
Old : sixtyfour 0
New : sixtyfour 255
caput sixtyfour $(( 16#87654321 ))
Old : sixtyfour 255
New : sixtyfour 2.27156e+09
caput sixtyfour $(( 16#32187654321 ))
Old : sixtyfour 2.27156e+09
New : sixtyfour 3.44254e+12
A camonitor will show 255, then 2.27156e+09, but not 3.44254e+12. A caget or a newly started camonitor will see the latest value.
Reason is this section in int64inRecord.c:
/* DELTA calculates the absolute difference between its arguments
* expressed as an unsigned 32-bit integer */
#define DELTA(last, val) \
((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last)))
It only checks for changes in the lower 32 bits of the value.
Maybe the motivation was to always perform an _unsigned_ comparison, but "UInt32" was copy/pasted instead of "UInt64"?
One fix should be to replace epicsUInt32 with epicsUInt64 in DELTA and where it's used.
Changed in epics-base: | |
status: | New → Fix Committed |
milestone: | none → 7.0.6.1 |
Changed in epics-base: | |
status: | Fix Committed → Fix Released |
> One fix should be to replace epicsUInt32 with epicsUInt64 in DELTA and where it's used.
Can you try replacing all three mentions of 'epicsUInt32' with 'epicsUInt64'?
It looks like int64outRecord.c is correct.