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>
2018
2019
2020
2021
2022
2023
2024
- 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>
2018
2019
2020
2021
2022
2023
2024
|