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: Sequencer remote pvPut CA delay (specified behavior?)
From: Tobin Weber <webert2@washington.edu>
To: Andrew Johnson <anj@aps.anl.gov>
Cc: <tech-talk@aps.anl.gov>, <eric@norum.ca>
Date: Mon, 13 Feb 2017 15:35:48 -0800
Thank you Andrew for that fantastic reply! That was very informative.
I'm going to clean up unnecessary uses of "monitor" statements in my
program. I'll definitely keep inputs and outputs separated, as well. I
was also using "epicsThreadSleep" extensively, so I'm going to try and
replace those with "when(delay)" where I can. The flushing of the CA
output queue explanation makes a lot of sense. And yeah, your
explanation for the small delay between the remote and local pvPut also
makes perfect sense. Thank you very much for the help.

And thanks Eric for the reference. I'll check out "Common Pitfalls and
Misconceptions” of the sequencer documentation.

Best,

Toby


On Mon, 2017-02-13 at 16:53 -0600, Andrew Johnson wrote:
> Hi Toby,
> 
> On 02/13/2017 03:53 PM, Tobin Weber wrote:
> > Basically, when the sequencer does a "pvPut" to a PV that
> > is located in an IOC that is not local to the machine, the write doesn't
> > appear to happen until after a subsequent "pvPut" is performed on a
> > local PV.
> 
> I don't agree with your analysis of what's actually happening,
> discussion below...
> 
> > For example, running the template in,
> > epics/template/makeBaseApp/top/example
> > 
> > and modifying the sncExample.stt file to read: 
> 
> A few inline comments:
> 
> > user@pc:~/example$ more exampleApp/src/sncExample.stt 
> > program sncExample
> > 
> > int local_pv;
> > int remote_pv;
> > 
> > assign local_pv to "Local:PV";
> > assign remote_pv to "Remote:PV";
> > 
> > monitor local_pv;
> > monitor remote_pv;
> 
> Since both local_pv and remote_pv are being used with pvPut, you almost
> certainly don't want their values to be updated by changes in their
> remote values as well, as that causes questions about who wins if you
> change the value in your code and the monitor fires at the same time.
> There is actually a defined answer to that particular question, but in
> most cases variables tend to be used as either inputs (which are
> monitored) or outputs (which are pvPut); I would recommend not using a
> single variable for both input and output at the same time, so just
> remove both monitor statements.
> 
> > ss ss1 {
> >     state init {
> >         when (delay(5)) {
> >             printf("sncExample: Startup delay over\n");
> >         } state low
> >     }
> > 
> >     state low {
> >     
> >         when (delay(5)) {
> > 
> >             // Setting a remote PV to 1
> >             remote_pv=1;
> >             pvPut(remote_pv);
> > 
> >             // Waiting for 5 seconds
> >             epicsThreadSleep(5.0);
> >             // Setting a local PV to 1
> >             local_pv=1;
> >             pvPut(local_pv);
> >                         
> >         } state high
> 
> 
> Calling epicsThreadSleep() is also worth avoiding in sequencer actions,
> it holds up the sequencer in the middle of the action block and thus
> prevents it from processing other transitions that might be triggered
> while the delay is in flight. Consider rewriting the state machine and
> using a separate when(delay(5)) state transition for the delay instead.
> 
> I think doing this will also have an effect on your results; I don't
> know the internals of the sequencer, but I suspect it flushes the CA
> output queue at the end of each set of actions, not between individual
> action statements. Your epicsThreadSleep() call appears in the middle of
> the set of actions though, so a flush at the end of the when() {} block
> won't have a chance to run until after the second pvPut() call has run
> anyway, thus causing the effect that you're seeing.
> 
> If you split this transition action into two separate states with a
> when(delay(5)) state transition between them (and just don't use
> epicsThreadSleep() at all in sequence programs), the flush will happen
> before the delay, so the state machine should then do what you're expecting.
> 
> >     }
> >     state high {
> >         when (0) {
> >         } state low
> >     }
> > }
> > 
> > with a "bo" record "Local:PV" running in local database, and a "bo"
> > record, "Remote:PV" on a different PC, here is what I observed with
> > camonitor when I ran the sequencer:
> > 
> > user@pc:~/EPICS_Apps/example/exampleApp/src$ camonitor Remote:PV
> > Local:PV
> > Local:PV  2017-02-08 13:58:41.904252 0  
> > Remote:PV 2017-02-08 13:58:31.645527 0  
> > Local:PV  2017-02-08 13:58:56.939562 1  
> > Remote:PV 2017-02-08 13:58:56.940262 1
> > 
> > It seems like the PV located on a different machine, "Remote:PV", does
> > not get written until after "Local:PV" is written. It should be 5
> > seconds before. The behavior is the same if states are changed in
> > between PV puts.
> 
> Ignoring the question of how well synchronized your two IOC's clocks are
> (since you're probably running both on the same PC) you should also be
> aware that the CA connection to a local PV will usually be faster than
> that to a remote one. It's not unexpected that Local:PV processes first
> even though the put to Remote:PV was queued first.
> 
> This does assume my point about flushing the CA output queue that I
> discussed above though, so the 0.0007 second time-difference between
> your two processing times is due to the fact that there's more work
> involved when the sequencer sends CA messages to an IOC running in a
> different process than when it sends them to another thread running in
> the same process as the sequence program.
> 
> HTH,
> 
> - Andrew
> 




References:
Sequencer remote pvPut CA delay (specified behavior?) Tobin Weber
Re: Sequencer remote pvPut CA delay (specified behavior?) Andrew Johnson

Navigate by Date:
Prev: Re: Sequencer remote pvPut CA delay (specified behavior?) Andrew Johnson
Next: Re: VAL field in Motor record Default unit Mark Rivers
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: Sequencer remote pvPut CA delay (specified behavior?) Andrew Johnson
Next: Re: Sequencer remote pvPut CA delay (specified behavior?) Benjamin Franksen
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, 14 Feb 2017 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·