C++ static constructors and SMP

Chris Johns chrisj at rtems.org
Mon Oct 21 15:26:05 UTC 2013


On 21/10/13 6:25 PM, Sebastian Huber wrote:
>
> C++ has some severe problems with the current SMP support in RTEMS.

It has some issues and these are being worked.

> If
> GCC is configured to use the RTEMS thread model some C++ constructs will
> end up in a fatal error.

Yes the RTEMS thread model is not suitable for SMP C++ because it is 
implemented using task variables. The RSB is using a patch to switch 
RTEMS to the POSIX thread model. The POSIX support does not have this 
limitation.

> If GCC is configured to use the POSIX thread
> model, then some C++ constructs lead to unpredictable run-time behaviour
> in case of missing resources.

Yes this can happen. It is surprising GCC's use of POSIX calls do not 
check the return code and this can result in silent failures. The simple 
work around is to configure RTEMS with a large number of POSIX resources.

> The C++ constructors are called in _Thread_Handler() (see also
> _Thread_Handler_is_constructor_execution_required()).  This function has
> a bug, since also one of the idle threads may get the duty to do this.

Correct, a non-primary processor can call static constructors while the 
primary processor passes and enters "main" (or Init) and this is wrong.

>
> On 2013-10-20 23:49, Chris Johns wrote:
>> On 20/10/13 1:21 PM, Gedare Bloom wrote:
>>>
>>> Have a pint for me.
>>>
>> Will do. Joel has been showing off his new Android Shoe phone today. Very
>> impressive.
>>>
>>> I assumed the c/c++ runtime initialization ran serially with other
>>> bootstrap/initialization on the bootup core. Guess I have not looked
>>> closely
>>> enough! I would think rtems initialization should "finish" before the
>>> application starts? Otherwise lots of badness could happen...
>>>
>> I agree. The bug is in threadhandler.c and the code to detect
>> 'doCons'. The
>> first core should take the lock and call the init and all other cores
>> should
>> spin waiting until it has finished. The current code detects if it
>> needs to
>> make the call.
>
> If you only configure one initialization thread, then the other
> processors will execute an idle thread.

This assumes the primary core which enters the Init thread is always 
calling the static constructors plus the primary code is calling Init. 
If a secondary core reaches the lock first it claims it and sets the 
done flag. When the primary processor arrives at the same location it 
sees construction is done and continues on to main. The construction 
call needs to be performed by the core that enters main and other cores 
need to enter idle (or run threads created during construction). This is 
made more complicated in terms of supporting standards because RTEMS has 
the 'Init' task tables rather than just supporting main (my preference).

I think having the primary core only call Init run the static 
constructors is a viable solution. I also think the logic in the 
_Thread_Handler_is_constructor_execution_required needs some work. I 
consider code that releases a lock it did not acquire as suspicious. 
That construct should be avoided in RTEMS.

> What happens on Linux if you
> start thread in one of the static constructors on SMP?

It runs and the user is responsible for managing this. What will not 
happen is 'main' is entered until all static constructors have been called.

Chris



More information about the devel mailing list