Comment 2 for bug 541396

Revision history for this message
Ben Franksen (bfrk) wrote : Re: [Bug 541396] Re: initialize VAL of an mbbi/o record with a string

On Mittwoch, 24. März 2010, Andrew Johnson wrote:
> I don't think this is likely to be possible anytime soon; only the
> record type code knows which fields make up the possible menu choices,
> and the record types don't get initialized until iocInit(), which
> currently can only happen after all the .db files have been loaded.

You are taking the way record instances are initialised in EPICS for
granted. Of course, what I requested cannot be done without inventing some
mechanism that deals with the problem you describe. Such a mechanism need
not be as invasive as allowing to add record instances at runtime, not by
far.

To illustrate, here is a sketch of a possible solution. The idea is to
postpone (delay) initialisation of certain fields until the proper phase of
iocInit, i.e. init_record, is reached. Which fields should be treated in
this way is specified in the record type dbd with a new field property
named 'lazy' of type yes/no, defaulting to no(*). A 'lazy' field has its
initial string value stored along with the record instance (and the actual
record field uninitialised) until after init_record has been called, after
which the string becomes invalid. The init_record procedure is responsible
for interpreting these strings and for initialising the actual record field
accordingly. The address of the init string could be put into a union
together with the actual field type; this would have to be handled by the
dbToRecordTypeH tool.

(BTW, this is quite similar to how link fields are handled now.)

The above specification of the init string's guaranteed lifetime has the
advantage of allowing efficient allocation and deallocation of the memory
needed for them. More specifically, it allows for a strategy in which
memory gets allocated in large chunks and filled by incrementing a "free"
pointer (except when the chunk is full), thereby amortizing the allocation
(and deallocation) cost. After the init_record phase, all the memory can be
freed in one go, leaving a large hole without danger of fragmentation.

With such a mechanism in place, another long-standing problem could be
solved immediately, namely that fields of array type cannot currently be
initialised in the db file (leading to awkward work-arounds like using an
SNL program, calling procedures from the ioc shell, etc...). We simply
treat array fields as 'lazy' by default. All that needs to be done is to
invent a suitable array syntax; for convenience and to discourage
proliferation of custom syntaxes and parsers, we could provide a routine in
base (to be called by init_record) that interprets a string in array syntax
by successively returning the individual elements (as single strings).
Given properly light-weight array syntax, this would be more or less a thin
wrapper around strtok. (Note it's ok to destroy the original array value
string in the process: it is not used any further and will be freed soon
afterwards anyway.)

(*) A usual, concrete syntax is only for illustration, other names may be
more appropriate, such as 'postpone' or 'delay'...