Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017 Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
<== Date ==> <== Thread ==>

Subject: Re: Record processing twice after upgrading to Base 3.15.5
From: Andrew Johnson <anj@aps.anl.gov>
To: "Dunning, Michael" <mdunning@slac.stanford.edu>
Cc: "Condamoor, Shantha" <scondam@slac.stanford.edu>, EPICS Tech-Talk <tech-talk@aps.anl.gov>
Date: Fri, 29 Sep 2017 17:56:39 -0500
Hi Michael,

On 09/29/2017 05:15 PM, Dunning, Michael wrote:
> In the driver there's a thread that periodically does I/O to the
> device, and this thread makes calls to process_record_li() after it
> parses the response from the device.  As far as I can tell, the
> process_record_li() routine is the only thing causing the record to
> process.

Okay, well the rest of the code you posted looks pretty standard.

I suspect the problem happens because the driver directly calls the
prset->process() routine instead of going through the IOC's dbProcess()
routine, which does all kinds of extra stuff.

I would recommend that you replace most of the process_record_li()
routine with the standard I/O Interrupt way of triggering record
processing, about which there are many examples and descriptions
available online, for example from slide #21 of
  http://www.aps.anl.gov/epics/docs/APS2015/01-EPICS-Device-Support.pdf

HTH,

- Andrew


> The double-processing starts about 10 seconds after iocInit (I/O is
> done approximately once per second). I don't yet understand what is
> going on in the driver for the first 10 seconds, but during that time
> the record appears to process normally, i.e., no double-processing.
> 
> This is the longin support from device support:
> 
> 
> struct {
>     long        number;
>     DEVSUPFUN   report;
>     DEVSUPFUN   init;
>     DEVSUPFUN   init_record;
>     DEVSUPFUN   get_ioint_info;
>     DEVSUPFUN   read_longin;
> }devLiEtherPSC={
>     5,
>     NULL,
>     NULL,
>     init_li_record,
>     NULL,
>     read_li,
> };
> epicsExportAddress(dset, devLiEtherPSC);
> 
> 
> static long init_li_record( struct longinRecord *pli )
> {
>     struct bitbusio     *pb = (struct bitbusio*)&(pli->inp.value);
> 
>     return ( etherPSCdrvInitRecord( pb, (struct dbCommon*) pli ) );
> 
> }
> 
> 
> static long read_li( struct longinRecord *pli )
> {
>     PSCRECORD        *PSCRecord;
> 
>     if ( ! (PSCRecord = pli->dpvt) ) return (2);
> 
>     if ( PSCRecord->nsta ) recGblSetSevr( pli, PSCRecord->nsta, INVALID_ALARM );
> 
>     pli->val  = PSCRecord->val.li;
>     pli->udf  = FALSE;
>     pli->pact = FALSE;
> 
>     return(0);
> }
> 
> 
> Now I see that compared to other non-asyn device support examples,
> this does look like kind of a mess.  In addition to making it
> thread-safe and checking pli->pact, does anyone have any suggestions
> on if/how I should restructure this?
> I've attached the driver and device support source files if anyone
> would be willing to take a look.
> 
> Thank you!
> 
> 
> 
> Michael Dunning
> SLAC National Accelerator Laboratory
> 2575 Sand Hill Road
> Menlo Park, CA 94025
> (650) 926-5200
> 
> 
> On Wed, Sep 27, 2017 at 2:43 PM, Andrew Johnson <anj@aps.anl.gov> wrote:
>> Hi Michael,
>>
>> Assuming the process_record_li() routine is for triggering record
>> processing after some I/O has been received, why is it unconditionally
>> setting pli->pact? This looks to me like a cross between an asynchronous
>> I/O completion routine (i.e. part of an asynchronous read_longin()
>> device support method) and something for triggering record processing.
>>
>> It isn't thread-safe; it accesses two pli fields in the second if()
>> condition without holding the record's scan-lock, which has been illegal
>> in all Base versions for quite a long time. Is there an associated
>> longin device support that goes along with this?
>>
>> Is the I/O operation the only thing that causes this record to process?
>> The fact that you're getting SCAN/INVALID alarms suggests that something
>> else is going on as well, but I can't tell what from just the code you
>> showed us.
>>
>> This might have worked in 3.14.12, but since it isn't following the
>> rules so there is no guarantee what it will do in other versions.
>>
>> Sorry to be so blunt,
>>
>> - Andrew
>>
>>
>> On 09/27/2017 03:30 PM, Dunning, Michael wrote:
>>> After upgrading to Base 3.15.5, we are seeing what looks like
>>> double-processing of a certain custom record type.  It is from our
>>> device support for Bira Ethernet Power Supply Controllers. The problem
>>> is with this record:
>>>
>>> record(longin, "ESB:BEND:2110:GainADCRaw")
>>> {
>>>     field(DESC, "ADC Gain Raw Data")
>>>     field(ASG,  "Internal")
>>>     field(DTYP, "EtherPSC")
>>>     field(INP,   "#L0 N0 P0 S50 @172.27.248.43")
>>>     field(FLNK, "ESB:BEND:2110:GainADC.PROC")
>>> }
>>>
>>>
>>>
>>> When the IOC boots, the record has STAT: SCAN and SEVR: INVALID.  If
>>> we camonitor this record, it seems to be processed twice:
>>>
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:15.648796 529
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:15.648796 529 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:16.549097 534
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:16.549097 534 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:17.449359 543
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:17.449359 543 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:18.349763 549
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:18.349763 549 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:19.250071 551
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:19.250071 551 SCAN INVALID
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:20.150256 549
>>> ESB:BEND:2110:GainADCRaw       2017-09-10 20:12:20.150256 549 SCAN INVALID
>>>
>>>
>>>
>>> The double-processing explains the SCAN and INVALID states.
>>>
>>> Here is the record processing routine from device support:
>>>
>>> static void process_record_li( ETHERPSCNODE *node, int signal, long i )
>>> {
>>>     PSCRECORD           *PSCRecord;
>>>     struct longinRecord *pli;
>>>     struct rset         *prset;
>>>
>>>     PSCRecord = &node->record[signal];
>>>     if ( ! (pli = (struct longinRecord*) PSCRecord->precord) ) return;
>>>
>>>     if ( pli->val != i  ||  pli->udf  ||  PSCRecord->nsta )
>>>     {
>>>         PSCRecord->nsta = NO_ALARM;
>>>         PSCRecord->val.li = i;
>>>         prset = (struct rset *) pli->rset;
>>>
>>>         dbScanLock( (struct dbCommon*) pli );
>>>         pli->pact = TRUE;
>>>         (*prset->process)( pli );
>>>         dbScanUnlock( (struct dbCommon*) pli );
>>>     }
>>> }
>>>
>>>
>>>
>>> I confirmed that this problem doesn't occur with Base 3.14.12.4.  Does
>>> anyone have any idea why this record would be processed twice with
>>> Base-3.15?
>>>
>>>
>>>
>>>
>>>
>>> Michael Dunning
>>> SLAC National Accelerator Laboratory
>>> 2575 Sand Hill Road
>>> Menlo Park, CA 94025
>>> (650) 926-5200
>>>
>>
>> --
>> Arguing for surveillance because you have nothing to hide is no
>> different than making the claim, "I don't care about freedom of
>> speech because I have nothing to say." -- Edward Snowdon

-- 
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon

References:
Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
Re: Record processing twice after upgrading to Base 3.15.5 Andrew Johnson
Re: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael

Navigate by Date:
Prev: Re: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
Next: RE: Notification of Archiver Appliance interruptions will.rogers
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
Navigate by Thread:
Prev: Re: Record processing twice after upgrading to Base 3.15.5 Dunning, Michael
Next: Motor module problem Jörn Dreyer
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <2017
ANJ, 03 Oct 2017 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·