RFC: Core constructors.

Chris Johns chrisj at rtems.org
Mon Dec 10 08:29:05 UTC 2007


Thomas Doerfler wrote:
> 
> Chris Johns schrieb:
>> In the cpukit/rtems/src/semcreate.c file a constructor reference is added:
>>
>> RTEMS_CTOR_REF( classic, semaphore );
>>
>> The references are at the leaf of the tree and pull in all above. Each 
>> constructor node has its pointer placed in a special section and a modified 
>> linker script pulls those pointers together. This is similar to the sysctl 
>> system in the TCP stack.
> 
> I like that approach. I do not know the details of the implementation,
> but I assume, that the order of the CTOR nodes is defined by the linker,
> so there is no way to define, whether let's say the semaphore CTOR is
> called before or after the msgqueue CTOR?

You do have control of sequence the calls are made. In the 
cpukit/rtems/src/sem.c file a constructor node is added:

RTEMS_CTOR( classic, semaphore, 8, _Semaphore_Manager_initialization );

and 8 is the initialisation slot for the semaphore manager. The CTOR node is 
located where the constructor code. For the semaphore it is the initialise 
manager call '_Semaphore_Manager_initialization'. I ordered the CTORs for the 
'classic' class the same as the original order.

In the semaphore create file a weak reference is made to the constructor node. 
This reference causes the initialise to be pulled in which places the node 
into the constructor table. The constructor table is formed with a simple 
linker script trick.

> I don't see a problem here right now, but it may come, when this
> mechanism is to be used for other areas of the RTEMS code.

The constructor calling order is controlled. This is not left to chance. This 
is different to C++ constructors. I was concerned about using the term 
constructor because of this. I am happy to remove constructor and use 
initializer or any other suggestion if it helps.

>> The downsize of this approach is the addition of extra data to hold the 
>> constructor and the reference. The constructor is currently 20 bytes and a 
>> reference is 4 bytes. The constructor size could be reduced as I did not try 
>> to make it as small as I could while playing. A constructor only adds to the 
>> size when you use the resource. In the case of the RTEMS API there are 13 
>> constructors and you would only get all if you used every API resource. In the
>> case of a task and semaphore application the overhead is 48 bytes. The 
>> smallest the constructor could be come is 12 bytes with usage restrictions.
> 
> As long as these tables/lists are ROMable, I don't see a big deal here.
> The code to call the initialization function would take roughly the same
> size, and the dummy no-* functions would add to this :-)

The nodes pointers are in the text section and the nodes are in the data 
section. The node are used to build the ordered list. This is the issue that 
needs more consideration. I wonder if I can iterate with just local stack data 
and no extra node data. This would allow the nodes to be placed in the const 
(text) section. It will take longer but then again performance is not the 
issue here.

> Another question: where do you actually create the CTOR node? Is it a
> part of the "semcreate" sourcecode file?

No the CTOR node is part of the initialise code. The create code has a 
reference to the CTOR node.

> This would mean, that if a module calls rtems_semaphore_release(), but
> nobody creates a semaphore, then rtems_semaphore_release() might try to
> work, but the whole semaphore manager is not yet initialized.

This should be a runtime error and if it is not we have a bug. I did consider 
this. If you create an application that obtains and releases a semaphore that 
is not created then you should get an error. Having the manager initialise 
should not make this error any different.

> Or is it in a separate sourcecode file which is referenced by each
> source file that implements the semaphore object?

This depends in the what you are doing. For the RTEMS API there is only the 
one reference in the create file.

>> I think the next layer up, the Classic, POSIX and ITRON API could be handled 
>> in a similar way. There could also be a BSP set of constructors. If this is 
> 
> This is beyond the current scope, but wouldn't it be nice to have a
> toll/checker, that could detect the relationship between different
> "blocks" of code?

I think this approach is performing a part of that function, but it is not 
automatic rather it is being engineered.

> The constructor mechanism is quite elegant and useful, but it would lead
> to nothing, when (stupid example) the msgqueue code would call functions
> in the semaphore manager, or (quite broadly used) a BSP calls printf.

I am not I understand what you mean with "lead to nothing".

If you use printf with a serial port the newlib code will pull in termios and 
this code creates a semaphore. This will cause the constructor node for 
semaphores to be included and so semaphore's initialisation will be called.

If you mean constructors being used in code that is not engineered correctly, 
then yes there would be no gain. The tool could be abused with poorly designed 
code how-ever I see the real positives. It provides a way to sequence 
initialisation without needing the RTEMS code to be modified or changed. From 
a quality point of view not touching code is important. That said we still 
need to control the call point for a specific class of constructors.

> If we would define packages (like network, IMFS, DOSFS, classic
> semaphores, classic message queues...) and would automatically check
> (based on a "relationship" file), that only wanted references to other
> packages are present (like DOSFS is based on libblock, but not on the
> BSP, and not on printf) then we might ensure, that the granularity of
> RTEMS could be easily maintained in the future.

Interesting idea. My concern is C offers no language support and so doing this 
would be difficult.

> 
> Hm. This is really a bit off topic. But maybe the direction would be
> quite nice :-)

Just a little. I am aiming lower at a smaller problem. :-)

Regards
Chris



More information about the users mailing list