[Rock-dev] Problems with C++ constructors and RTEMS

Joel Sherrill joel.sherrill at gmail.com
Sun Sep 18 00:27:40 CEST 2011


On Sat, Sep 17, 2011 at 4:23 PM, Anita <ana.vazquez.alonso at gmail.com> wrote:
> Dear Joel,
>
> First of all, I would like to thank you for your help. Your answer indeed
> clarifies me how resources are managed in RTEMS.
>
> Now the execution continues until a ioctl SIOCGICONF failed in onmiORB, but
> that's another story,

Have you run one of the network demos from RTEMS on your
target board?  That way we would be sure it isn't just a basic
setup issue.  If you are using qemu or some other simulator,
it can be tricky to get the network magic right on the host OS,
RTEMS system, and simulator.

Are you sure the network stack for RTEMS is initialized, the interface
is up, and has a route?

> and I feel I'm pretty close to get
> Rock running on top of RTEMS :)

;)

> Regarding the binary size, sorry, 32 mb is the output of ls -l (not really
> indicative). Below is the output of i386-rtems-size:
>
> i386-rtems-size -x -A message_producer_test
> message_producer_test  :
> section                  size       addr
> .text                0x479764   0x100000
> .init                     0xd   0x579764
> .fini                     0x8   0x579771
> .rodata               0xc0d20   0x579780
> .eh_frame            0x126ce8   0x63a4a0
> .gcc_except_table     0x5988c   0x761188
> .ctors                  0x2c4   0x7bb000
> .dtors                  0x298   0x7bb2c4
> .jcr                      0x4   0x7bb55c
> .data                  0x5500   0x7bb560
> .bss                   0xad20   0x7c0a60
> .stab                0x653610        0x0
> .stabstr             0xf3dc93        0x0
> .comment                 0x2b        0x0
> Total               0x1c5c45b
>
> Much smaller, although still too big for the Xilinx FPGAs with LEON2. But
> I'll worry about that later.

I think it you will strip that, it will still be much smaller.  It has debug
information.

That will leave you with (to me) a large executable since
the .text section is 4.5Mb but given that you have TCP/IP,
OmniORB and who knows what else, it isn't that unexpected.

Does this executable contain an initial file size image by any
chance?

> Thank you and kind regards,

No problem.  We all want you to be successful. :)

--joel sherrill
RTEMS
> Ana
>
> On Fri, Sep 16, 2011 at 8:47 PM, Joel Sherrill <joel.sherrill at gmail.com>
> wrote:
>>
>> On Fri, Sep 16, 2011 at 4:45 AM, Anita <ana.vazquez.alonso at gmail.com>
>> wrote:
>> > Hi,
>> >
>> > I managed to compile and link all the dependencies libraries together
>> > with RTEMS 4.10.1 and Newlib, producing a final binary of about 32Mb.
>>
>> That's rather large.  Is that the output of "size" or the file size (e.g.
>> ls -l)
>>
>> > I run it with QEMU but a problem in  runtime arose:
>> >
>> > The problem happens inside a c++ constructor, called from
>> > __do_global_ctors_aux (which if I understand it correctly, basically
>> > call all the constructors from the table of pointers to constructor
>> > defined in the .ctors section (i386-rtems-objdump -s -j .ctors
>> > message_producer_test | vim -)).
>> >
>> > __do_global_ctors_aux is called from RTEMS (_Thread_Handler
>> > ->INIT_NAME -> _init).
>> >
>> > The constructor is part of omniORB, omni_mutex::omni_mutex
>> > (http://pastebin.com/Pcd50Bni). Inside this constructor, a call to
>> > pthread_mutex_init is produced.
>> >
>> > From the gdb log (http://pastebin.com/QrRxWxse) I fear that the
>> > problem is allocating resources inside pthread_mutex_init, actually in
>> > objectallocate.c -> chainget.c -> chain.inl.
>> >
>> > At first, I though the problem was related to RTEMS running out of
>> > memory (and even tried to increase QEMU memory), but after taking a
>> > look to chain.inl, I think that the problem may be the omni_mutex
>> > constructor calling pthread_mutex_init and therefore allocating
>> > resources before RTEMS is completly ready. Although, RTEMS is the one
>> > calling __do_global_ctors_aux.
>> >
>> > I hope any of you can spread some light. In the meantime, what I have
>> > in mind is modify omniORB and delay the pthread_mutex_init call in
>> > omni_mutex.
>>
>> RTEMS != Linux. :-D
>>
>> I am sure that didn't help at all but it is a lead in to try to explain
>> the philosophical difference between RTEMS and Linux that
>> lead you to get this error.   The error is in fact an out of resources
>> error.  RTEMS was designed for to target systems with hard
>> resource requirements.  In this design view, it is better to preallocate
>> as much as possible so you don't have to deal with running out
>> of resources at run-time.  This makes the resulting system
>> safer and less likely to have a weird failure mode in this situation.
>>
>> In RTEMS you configure the maximum number of each type of
>> object you want.  The defaults tend to be 0.  Memory is reserved
>> for RTEMS separate from the C Program Heap based upon your
>> cofniguration requests.  The sample in testsuites/samples/ticker
>> has the following configuration in the file system.h
>>
>> ============================================
>> #include <bsp.h> /* for device driver prototypes */
>>
>> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>> #define CONFIGURE_MAXIMUM_TASKS             4
>> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>> #define CONFIGURE_EXTRA_TASK_STACKS  (3 * RTEMS_MINIMUM_STACK_SIZE)
>>
>> #include <rtems/confdefs.h>
>> ============================================
>>
>> The application says is needs a console (stdio) and clock tick (time
>> passage) device drivers.  It has 4 Classic API tasks maximum.
>> It is using a Classic API style initialization task -- the alternative
>> is a POSIX Threads initialization thread.  And each of the tasks
>> it is creating has a stack larger than the minimum required.  So
>> we reserve some extra memory for those.  See the rtems_task_create()
>> calls in init.c for the stack sizing.
>>
>> If you looked at the hello world sample, it wouldn't have the Clock
>> driver and would only have one task.
>>
>> In your case, you need to define CONFIGURE_MAXIMUM_POSIX_MUTEXES
>> to however many is required.
>>
>> With all that background on the hard limit focus on RTEMS configuration,
>> RTEMS also has an "unlimited object mode" and "unified workspace" option.
>> This is probably more useful for you at this stage.  This lets you
>> configure
>> that you want a potentially unlimited number of a class of objects and
>> that
>> you want RTEMS Workspace and the C Program Heap to be the same
>> pool of memory.
>>
>> #define CONFIGURE_MAXIMUM_POSIX_MUTEXES \
>>   rtems_resource_unlimited( 5 )
>> #defined CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES \
>>   rtems_resource_unlimited( 5 )
>> #define CONFIGURE_UNIFIED_WORK_AREAS
>>
>> That says that POSIX mutexes and condition variables are "unlimited"
>> but the set is extended 5 instances at a time.  Create the sixth and
>> instances 6-10 will be added to the inactive pool for that object class.
>>
>> The full set configuration macros are (hopefully) well documented here:
>>
>>
>> http://rtems.org/onlinedocs/doc-current/share/rtems/html/c_user/c_user00416.html
>>
>> Also .. any time you see a call from _Objects_Allocate() fail, it is
>> either
>> a maximum objects issue or not accounting for variable memory like
>> stack space or message buffers which must be allocated when the
>> object instance is created.
>>
>> Since you are porting a software package, let me throw out another
>> thought.  There is likely a fixed base set of objects the package creates
>> such as for global mutexes or message queues.  A user of package X
>> will create instances of objects that it defines.   So if the package X
>> has
>> a macaroni object that requires a mutex, condition variable, and
>> a message queue, then you can let the end user of package X know that
>> for each macaroni instance, they need to reserve A, B, and C.  For certain
>> cases, like the tasking in Ada and Go, we provide higher level
>> configuration
>> helpers like CONFIGURE_MAXIMUM_ADA_TASKS to encapsulate this
>> configuration information.
>>
>> I know my answer is a bit over the top but I want you to really understand
>> this
>> part of RTEMS.  Figuring out how many of each kind of object when porting
>> a
>> software package is always a challenge.  Embedded developers focused on
>> safe, reliable systems don't like surprises and using various techniques
>> to
>> avoid running out of resources at run-time is a big part of it.  It is
>> not uncommon
>> for malloc() to be forbidden after system initialization.
>>
>> FWIW I would like to clean this up and make it a blog entry for RTEMS.
>> So if anything is unclear, let's make it clear to you. :)
>>
>> --joel sherrill
>> RTEMS
>>
>>
>> > Kind regards,
>> > Ana
>> >
>> > P.S. In order to simplify the understanding of the problem, I attach
>> > the code from mutexinit.c (http://pastebin.com/cC6G2UjF), and since
>> > _Thread_Disable_dispatch(), _POSIX_Mutex_Allocate() and
>> > _Thread_Enable_dispatch() are inline functions, I also attached the
>> > unrolled version (http://pastebin.com/MxwXCCj5).
>> >
>
>


More information about the Rock-dev mailing list