EPICS Controls 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  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: race condition with calcout & CA input links?
From: Andrew Johnson <[email protected]>
To: "Konrad, Martin" <[email protected]>
Cc: "[email protected]" <[email protected]>
Date: Tue, 10 Sep 2013 17:16:58 -0500
Hi Martin,

I cannot fully explain what's going on in your first testing database, although I think you already have a workaround with help from Mark.

On 09/10/2013 10:57 AM, Konrad, Martin wrote:
1. Using a calcout record that has its input CP-linked to DMOV. => The
calcout record processes twice for each 1-0-1 transition but it doesn't
reset doneMovingGate_. I guess this happens because for some reason it
reads 1 all the time.

In your first database both LNK1 and LNK2 of your sequence record have PP links to the DMOV bi record. The calcout record reads the DMOV value using a CP input link. There are no delays set in the seq record, so as soon as the LNK1-triggered process of DMOV=0 finishes the LNK2 will fire, setting DMOV=1 and re-triggering DMOV. Record processing happens at a higher priority than CA operations, so the calcout record may not actually get triggered until *after* the second time DMOV processes.

Now in practice there are a few queues and possible thread switches involved there. The sequence record deliberately queues each link processing step as a separate callback operation (to avoid any chance of calling itself recursively according to the code comments). The CA monitor on the DMOV value also results in a monitor update being queued whenever that value changes. Since that's a local PV the CA message between the server and client does not actually go through a network buffer, but a thread switch is still required so the client-side thread that processes the calcout record probably won't get to run until after both the earlier database operations have completed.


Even so, the CA event queue stores a copy of the value with each monitor queued, so I would still expect the first calcout process operation to see a zero value and the second a 1.

Ralph or Jeff, can you explain this?

Here's the simplified database which I've tested this with (3.14 branch, on Linux), I replaced the calcout and bo with another bi:

record(seq, mk:seq) {
  field(DOL1, "0")
  field(LNK1, "mk:DMOV PP MS")
  field(DOL2, "1")
  field(LNK2, "mk:DMOV PP MS")
}
record(bi, mk:DMOV) {
  field(ZNAM, "zero")
  field(ONAM, "one")
}
record(bi, mk:DET) {
  field(ZNAM, "zero")
  field(ONAM, "one")
  field(INP, "mk:DMOV CP")
}

I set up a camonitor on both mk:DMOV and mk:DET and (after it first changes to one) I never see any updates from mk:DET at all. I trigger the processing with "caput mk:seq.PROC 1"

tux% camonitor mk:DMOV mk:DET
mk:DMOV                        <undefined> zero UDF INVALID
mk:DET                         2013-09-10 15:50:37.273911 zero
mk:DMOV                        2013-09-10 15:51:28.185105 zero
mk:DMOV                        2013-09-10 15:51:28.185125 one
mk:DET                         2013-09-10 15:51:28.185228 one
mk:DMOV                        2013-09-10 15:51:42.439874 zero
mk:DMOV                        2013-09-10 15:51:42.439896 one
mk:DMOV                        2013-09-10 15:53:13.114035 zero
mk:DMOV                        2013-09-10 15:53:13.114068 one
mk:DMOV                        2013-09-10 16:04:03.779103 zero
mk:DMOV                        2013-09-10 16:04:03.779126 one

I know the mk:DET record is processing from setting TPRO:

CAS-client: Process mk:seq
cbLow: Process mk:DMOV
cbLow: Process mk:DMOV
scanOnce: Process mk:DET
scanOnce: Process mk:DET

Why is the mk:DET record getting processed twice by the CP link but reading the same value in both cases? The DMOV record is queueing two different enum values as shown by the above camonitor output, and changing both records to longin makes no difference.

I get exactly the same behaviour with 3.15, and going back as far as 3.14.8 when I gave up.

Now my question is: Why does the calcout record miss the 0 while my
camonitor (which also connects via Channel Access) gets the 1-0-1
transition reliably? As far as I can see from biRecord.c
db_post_events() is issued right before the forward links are processed.
So if it works with forward links (case #3 from above) why doesn't it
with a CP link (case #1)? Is this some sort of a race condition?

I don't think this is likely to be caused by a race condition because there are locks everywhere, but I can't explain it yet.

- Andrew
--
Advertising may be described as the science of arresting the human
intelligence long enough to get money from it. -- Stephen Leacock

References:
race condition with calcout & CA input links? Konrad, Martin

Navigate by Date:
Prev: Re: motor record: soft motor & DMOV Konrad, Martin
Next: EtherCAT and NI slave chassis [SEC=UNCLASSIFIED] LYNCH, Damien
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: race condition with calcout & CA input links? Konrad, Martin
Next: Multiple patterns/ .sub files for the same .db file Tito Körner
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·