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  <20082009  2010  2011  2012  2013  2014  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  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Weird waveform behavior
From: Tim Mooney <[email protected]>
To: Dirk Zimoch <[email protected]>
Cc: [email protected]
Date: Wed, 18 Jun 2008 11:50:30 -0500


Dirk Zimoch wrote:
Hi Chen,

we run into similar problems at the SLS recently. The problem is the difference between how we think array support should work and how it is actually implemented. All EPICS records which deal with arrays always copy buffers. Manipulating pointers is not supported!

I studied this array-field business recently to see what sorts of things were possible for the sscan record. (The sscan record maintains double buffered arrays. I wanted to post current data to display clients, and old data to data-storage clients.) It turns out that there is some flexibility you can exploit, if you are writing record support. Device support doesn't enjoy any flexibility, however, so I agree with Dirk in the context of the question he was answering. I'm replying mostly to get what I've learned on the record before I forget all the details. (Sorry this is so long. It's completely ignorable if you're not interested in writing record support for array fields.)

Executive summary:  You can manipulate buffer pointers in some cases,
but there are limitations on what you can accomplish by doing it.  The
limitations for gets are different from the limitations for monitors.

In the following, the array field has the attribute SPC_DBADDR, and
record support implements the routines cvt_dbaddr() and get_array_info().
Here's what happens when a client does a get (either ca or db) on the
array field:

1) cvt_dbaddr() is called (twice; I don't know why) and is supplied with
a struct dbAddr argument which names the field the client wants.
cvt_dbddr() fills in the dbAddr structure to describe the field data,
and to specify the buffer pointer.  It doesn't matter what the buffer
pointer actually points to yet, though it must be of the correct type.

2) get_array_info() is called, with the struct dbAddr arg that
cvt_dbaddr() modified.  Thus, get_array_info() sees both the field name
and the buffer pointer written by cvt_dbaddr().  get_array_info() can
change the buffer pointer in the dbAddr structure, and this is the
buffer pointer that will actually be used to transfer data.

So, if we restrict attention to gets, a record can do whatever it wants
with buffer pointers, as long as its get_array_info() routine supplies
the correct buffer pointer, and the record maintains the data and the
pointer until they are read by the client.  The record cannot know when
a client will want to read the data, however, so steps must be taken
to defend clients from stale or partially written data.

Monitors are a little more indirect, and the record is significantly
more constrained in the pointer manipulation it can get way with.
Here's what happens when a client monitors an array field:

1) cvt_dbaddr() is called as for a get.

2) get_array_info() is called twice, and CA evidently caches the dbAddr
structure, or at least the buffer pointer (the dbAddr's pfield) that
get_array_info() wrote to that structure.

3) when the record wants to post the array field, it must post the
buffer pointer (pfield) from (2) to get the array data sent to the
client whose monitor request resulted in that call to get_array_info().
(Ned Arnold discovered and coded around this in his initial development
of double buffered arrays for the scan record.)  The posting is merely
an advertisement that array data are available; it doesn't directly
transfer array data.

4) get_array_info() is called when channel access gets an opportunity to
send data to the client, and it is supplied with the field name and the
buffer pointer that it wrote earlier.  get_array_info() is free to write
any buffer pointer it wants to the dbAddr's pfield at this time, so it
can choose which data will be sent to the client.

Thus, the association between an array field name and the data sent to a
client monitoring that field is made by the buffer pointer written by
get_array_info(), and get_array_info() has two opportunities to write
that pointer:  The first write (when the monitor is connected)
determines what pointer the record must post to notify the client that
data are available for the field.  The second write (at data-transfer
time) determines what data will actually be sent to the client.

However, get_array_info() doesn't know whether it's doing the first write
or the second write, because clients can cause get_array_info() to be
called at any time.  So some of the potential flexibility in this
mechanism may not actually be available to the record.

I think it might be ok for the record to write an artificial buffer
pointer in the call to cvt_dbaddr(), and thereby to tell itself that the
ensuing call to get_array_info() is for the purpose of connecting, and
not the result of a monitor posting.  I haven't tried this yet, but it
would allow the sscan record more effectively to distinguish display
clients from storage clients.  (Currently, when the record posts old data
to storage clients it is also posting new data to display clients, and
vice-versa.)

I don't, by the way, expect all this array stuff to remain backward
compatible forever, just because it's being exploited by the sscan record.
I haven't seen any other record that relies on these details, and I do
not want be the one to quash new development in this area.  If a better
mechanism should be developed, I'll be happy to code to it.

--
Tim Mooney ([email protected]) (630)252-5417
Beamline Controls & Data Acquisition Group
Advanced Photon Source, Argonne National Lab.

References:
Weird waveform behavior Zhichu Chen
Re: Weird waveform behavior Dirk Zimoch

Navigate by Date:
Prev: Re: Weird waveform behavior Zhichu Chen
Next: building base, convertRelease.pl ? John Dobbins
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Weird waveform behavior Zhichu Chen
Next: building base, convertRelease.pl ? John Dobbins
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  <20082009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·