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  <20112012  2013  2014  2015  2016  2017  2018  2019  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019 
<== Date ==> <== Thread ==>

Subject: RE: When a record is changed twice very fast, camonitor only detects first change
From: Mikel Rojo <mikelrojo5@hotmail.com>
To: <mbec@gemini.edu>, <anj@aps.anl.gov>, <mooney@aps.anl.gov>
Cc: tech-talk@aps.anl.gov
Date: Mon, 23 May 2011 20:01:08 +0200
> Date: Mon, 23 May 2011 11:26:27 -0400
> From: mbec@gemini.edu
> To: mikelrojo5@hotmail.com
> CC: tech-talk@aps.anl.gov
> Subject: Re: When a record is changed twice very fast, camonitor only detects first change
>
> Hi Mikel,
>
> you may reconsider why your snl would need to pvGet on a channel you set
> to be monitored.
> As far as receiving monitors, stringin/out have MPST/APST fields - those
> will let you post value/archive monitors either On Change or Always
> (former is the default). In your test case, check how the record behaves
> once you set:
>
> caput RECORD.MPST Always
>
> Cheers,
> Matthieu

Hi Matthieu,

Thanks for your quick reply! Yes, the pvGet is completely unnecessary. I put it there more for a reference to indicate the process part deals with using the value that's on it (though actually I did have it included in my original code, but I realized it was unnecessary when I was transcribing it in my original message). I didn't know it would do any harm but of course if it's unnecessary, best not to have it. I tried changing the MPST field and it worked exactly as it was supposed. Also simplified the code, since with this field changed, it is no longer necessary to clear the record each time a new string sent to it. The old value can stay where it's at until a new one comes along.

Just one note, these two records do appear in VDCT, however I did not find them documented in the record reference manual, neither in the stringin/out chapters nor in the "fields that (almost) all record types have" chapters. Do you know if they are documented somewhere?

> Date: Mon, 23 May 2011 11:01:01 -0500
> From: mooney@aps.anl.gov
> To: mikelrojo5@hotmail.com
> CC: tech-talk@aps.anl.gov
> Subject: Re: When a record is changed twice very fast, camonitor only detects first change
>
> Mikel,
>
> What is the stringin record's SCAN field set to? If it's not "Passive",
> then "pvPut(input)" will not cause the record to process, and this will
> prevent the new value of the VAL field from being posted. (Channel access
> will post the value of any non-VAL field that it writes to, but it defers
> to the record for VAL fields.)
>
> Tim

Hi Tim,
No, the SCAN field is I/O Intr. since it needs to be updated each time it receives the interrupt from the HW.
Still, the VAL field was being changed properly (the record was processing correctly) but the monitor was not getting the proper feedback.

I changed the MPST field as Matthieu suggested and it worked. Thanks for your help!

> From: anj@aps.anl.gov
> To: tech-talk@aps.anl.gov
> Subject: Re: When a record is changed twice very fast, camonitor only detects first change
> Date: Mon, 23 May 2011 12:02:55 -0500
> CC: mikelrojo5@hotmail.com
>
> Hi Mikel,
>
> On 2011-05-23 Mikel Rojo wrote:
> > I don't understand how camonitor can say that a pv has one value, while
> > with caget we can see that it has a different one. I tried stopping the
> > monitor before clearing the variable and then starting the monitor again
> > afterwards but it does not change anything. I am using the latest
> > version of base (3.14.12.1) and sequencer (2.0.13). I would really
> > appreciate any help. Thank you in advance.
>
> In addition to the comments Matthieu made about your pvGet() being unnecessary
> and possibly even harmful, I recommend that you never change the value or use
> pvPut() on a variable that has a monitor set on it. There is a known race
> condition in the sequencer such that a monitor event can arrive and change a
> variable's value while the sequencer is still processing the action statements
> from a previous state transition. If you want to update the value of a PV
> that you're monitoring, create a second variable assigned to the same PV and
> use that variable for all pvPut() operations. Your code also needs to allow
> for the fact that the pvPut() can cause another monitor to be queued and thus
> set your event flag again.

Thanks, Andrew, I was not aware of this. I'll keep it in mind for next time. However, with the MPST field fix Matthieu suggested, this is no longer necessary. The only reason why pvPut was necessary was to clear the record so that in case the same input arrived the monitor would still be triggered. Now, since the monitor is triggered also when the new input is the same as the old one, the old value can sit in the record, and no pvPuts are necessary.

> There is another issue that you might also be hitting, although I don't think
> so in this case: A ca_monitor() of a string PV that changes often is not
> guaranteed to always send the actual character string that caused the monitor,
> it might skip one or more values from a very busy record. Here's why:
>
> When a record processes and triggers a monitor, the code pushes an event
> object onto the send queue for each client, but to save memory we don't copy
> string or array values into that object (it only has enough space for scalars
> up to size double). When the client's send thread later executes to forward
> that value it will lock the record and copy the string value out of the record
> field into the TCP socket buffer, but if the record has processed since the
> original value was queued it will be given the newer string instead.

This might be the case anyway. Even though the MPST field was the fix I needed, I still don't understand why the monitor didn't update itself when the record was changed twice in the same routine. A string is written to the record, the monitor is activated, the string is immediately cleared and yet the monitor still sees the string there. However, this is the opposite of what you say. The old value remains and the new one doesn't show. Even though it's not necessary to fix the problem anymore it still would be interesting to know what exactly is the monitor process and why it gets stuck with the first change and doesn't realize the second.

> - Andrew

Thanks all for your help and quick replies!
Best regards,
Mikel

> On 05/23/11 11:02, Mikel Rojo wrote:
> > Hi,
> >
> > I searched tech-talk for something similar but haven't found anything. I
> > hope I am not submitting an old claim. I have a sequencer program that
> > basically monitors a stringin record for when a command arrives from
> > some HW. Here is the basics of the program:
> >
> > program xxx
> >
> > /*RECORD is a stringin record that receives a string command when the HW
> > sends it*/
> > string input; assign input to "RECORD"; monitor input;
> > evflag change; sync input change;
> >
> > ss xxx {
> > state IDLE {
> > entry {
> > efClear(change);
> > }
> > when(efTestAndClear(change)) {
> > } state PROCESS
> > }
> >
> > state PROCESS {
> > when(1) {
> > pvGet(input);
> > [...some processing is done...]
> > sprintf(input,"");
> > pvPut(input);
> > } state IDLE
> > }
> > }
> >
> > However, the PROCESS state is only reached when the input string is
> > different from the previous one. Here is what happens:
> > 1. First the program is idle waiting for an input: camonitor and caget
> > RECORD both return ""
> > 2. "STRING" gets sent from the HW and dumps on the RECORD
> > 3. the monitor detects the change and raises the change flag
> > 4. camonitor changes to "STRING"
> > 4. PROCESS state begins, "STRING" gets loaded on the input variable
> > 5. at the end of processing input is set to ""
> > 6. with pvPut, the string "" gets written onto RECORD, this is done so
> > that the record can reprocess in case the same string comes in again.
> > 7. program waits in idle state
> > 8. At this point, caget RECORD returns "", however camonitor RECORD is
> > still stuck on "STRING", this does not change after waiting
> > 9. If a new string is written to RECORD from the HW, the camonitor
> > detects a change and starts the process, but if it is the same "STRING"
> > again, the monitor believes there has been no change and does not
> > trigger the process
> >
> > I don't understand how camonitor can say that a pv has one value, while
> > with caget we can see that it has a different one. I tried stopping the
> > monitor before clearing the variable and then starting the monitor again
> > afterwards but it does not change anything. I am using the latest
> > version of base (3.14.12.1) and sequencer (2.0.13). I would really
> > appreciate any help. Thank you in advance.
> > Mikel Rojo
>

References:
When a record is changed twice very fast, camonitor only detects first change Mikel Rojo
Re: When a record is changed twice very fast, camonitor only detects first change Matthieu Bec

Navigate by Date:
Prev: Re: When a record is changed twice very fast, camonitor only detects first change Andrew Johnson
Next: Re: caGateway crashes / use of *MustSucceed functions Jim Thomas
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019 
Navigate by Thread:
Prev: Re: When a record is changed twice very fast, camonitor only detects first change Matthieu Bec
Next: Re: When a record is changed twice very fast, camonitor only detects first change Tim Mooney
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  <20112012  2013  2014  2015  2016  2017  2018  2019 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·