Experimental Physics and Industrial Control System
Hi Michael,
On 2013-01-03 Michael Davidsaver wrote:
>
> Recently I was looking at how array fields are handled in database
> processing and RSRV. In the process I noticed a way to allow double
> buffering (and possible more creative schemes) of BPTR in the
> waveformRecord.
>
> This involves playing games with the array offset returned by the
> get_array_info() record support function, and taking advantage of how
> this offset is used in dbConvert.c. By doing this I can convince
> dbGet() and dbPut() to read/write from almost arbitrary locations which
> can change with each call.
I wouldn't regard setting *no_elements and *offset as "playing games", I think
it's perfectly reasonable for a record to implement multiple-buffering by
dividing the data buffer into a series of smaller segments and using *offset
to select the current segment within the buffer.
> > static long get_array_info(DBADDR *paddr, long *no_elements, long
> > *offset) {
> > ...
> > if(prec->bact) {
> > /* cause caller to access buf[1] */
> > *offset = (prec->buf[1] - prec->buf[0]) /
> > dbValueSize(prec->ftvl); } else {
> > *offset = 0;
> > }
>
> http://bazaar.launchpad.net/~epics-core/epics-base/array-opt/revision/12397
If I've understood your code correctly, it's relying on *undefined behavior*
because you're subtracting pointers to two differently allocated buffers to
calculate the *offset value. If the C compiler detects this it is quite at
liberty to do anything it likes at that point.
If you kept the original single buffer allocation however and just split it
into two parts logically there would be no undefined behavior. I would think
this might be slightly simpler to implement as well, although there's probably
not much difference.
> There is also an example device support.
>
> http://bazaar.launchpad.net/~epics-core/epics-base/array-opt/revision/12398
You will need to rename the record type before it has any chance of getting
into Base BTW, but you probably guessed that already...
> Now that I have this working I'd like to create a mechanism which
> doesn't involve abusing 'offset'. So far I've been thinking of allowing
> get_array_info() to provide a replacement pointer (in addition to offset
> and length) either by adding another argument, or allowing modification
> of the DBADDR argument.
I think there may be problems trying to change the pointer, because that's the
fundamental value that the server code uses to identify the field that was
subscribed to — it's the only field-specific parameter the record passes to
db_post_events() so it must match the pointer given out when the subscription
was created.
> The entire branch
>
> https://code.launchpad.net/~epics-core/epics-base/array-opt
>
> There is also some in-progress changes related to optimizing dbConvert.c.
Interesting; have you done any bench-marking of that optimization?
- Andrew
--
There is no such thing as a free lunch. When invited for lunch,
it is best to check if you are there to eat, or to be eaten.
-- Clive Robinson
- Replies:
- Re: double buffered waveformRecord Michael Davidsaver
- References:
- double buffered waveformRecord Michael Davidsaver
- Navigate by Date:
- Prev:
double buffered waveformRecord Michael Davidsaver
- Next:
Re: double buffered waveformRecord Michael Davidsaver
- Index:
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:
double buffered waveformRecord Michael Davidsaver
- Next:
Re: double buffered waveformRecord Michael Davidsaver
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
<2013>
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024