C++ static constructors and SMP

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Oct 21 18:30:27 UTC 2013


On 10/21/2013 04:59 PM, Chris Johns wrote:
>>
>> 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. 

Once the low-level single threaded initialization is done, there is no 
primary core.  All cores are equal.

> 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. 

On my Linux this is not true.  The following program

#include <pthread.h>
#include <stdio.h>

void *thread(void *arg)
{
     printf("thread\n");
     while (1);
}

__attribute__((constructor)) void ctor(void)
{
     pthread_t id;
     int eno = pthread_create(&id, NULL, thread, NULL);
     while (1);
}

int main()
{
     printf("main\n");

     return 0;
}

outputs

gdb ./a.out
GNU gdb (GDB) SUSE (7.5.1-2.1.1)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/sh/tmp/a.out...done.
(gdb) r
Starting program: /home/sh/tmp/a.out
[New Thread 0x7ffff7810700 (LWP 30862)]
thread
^C^
Program received signal SIGINT, Interrupt.
0x00000000004006ba in ctor ()
(gdb) info threads
   Id   Target Id         Frame
   2    Thread 0x7ffff7810700 (LWP 30862) "a.out" 0x0000000000400692 in 
thread ()
* 1    Thread 0x7ffff7fd8700 (LWP 30858) "a.out" 0x00000000004006ba in 
ctor ()
(gdb)

So the RTEMS behaviour is  perfectly in line with the Linux world in 
this respect.

The only guarantee we should make is: exactly one thread will execute 
the global constructors.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.




More information about the devel mailing list