Realtime compliant Dynamic Memory Management


In many realtime embedded systems, you do not want to use dynamic memory management via the standard C library functions malloc() and free(). Moreover, in certain secure environments you are not allowed to use those functions. The main reason for not using heap functions is fragmentation: after allocating and freeing chunks of memory, the heap gets cluttered with areas which are in use, and areas which are free and it becomes more and more difficult to find a suitable area for some object or structure which must be allocated at runtime.

Instead of using the heap, the OO RTX offers static pools for various purposes:
If you want to prevent the use of these pools, you should override the property CG::Event::BaseNumberOfInstances so it has no value.

In the profile which comes with your product, we have provided a stereotype called StaticComponent, which sets certain properties in Rhapsody to use the dynamic memory functions of the OO RTX which work on the three buffer pools. Next to that, any call to malloc() and free() is mapped onto the appropiate equivalent via macros which are included in the generated sources and OO RTX.

When allocating a chunk, the function which operates on the buffer pools tries to allocate the chunk in the pool which matches the size needed; thsi way we try to prevent fragmentation.

Events

The pool for the events is actually a pool for pointers to events: the size of an event will vary depending if you are using arguments in events. So the pointer array is allocated staticly. The events itself are allocated in the buffer pools: depending on any object you allocate dynamically you might want to finetune the size of the elements in the small buffer to the size of your largest event.


Timeouts

The timeouts are stored in their static pool. Because the size of a timeout structure is always the same, the pool itself holds the timeouts. A timeout is actually translated into an event: the timeout structure itself remains in the timeout pool, but its address is inserted in the event (pointer) pool.


Objects

You may use singletons in your Rhapsody model or use the three static pools (small, medium and large buffers) for allocation of your objects. It is also possible to use a mixture of static and dynamic memory:  you can disable the constant NO_MALLOC which prevents the memory management of the OO RTX of calling malloc() when a static buffer pool is exhausted. If you inspect the memory map file created by the linker (verify the settings in your IDE to create one), you can calculate the size of your objects  - provided you start with static allocated objects - and see if you can finetune the dimensions of your three static buffer pools. You can use the high water marks to verify how much these are used at runtime.


Mapping malloc() and free()

If you have defined NO_MALLOC (e.g. by selecting the StaticComponent stereotype), malloc() and free() will be mapped to RiCAllocator_getMemory() and RiCAllocator_returnMemory(). This means also if you use malloc() and free() in your Rhapsody user code, these will be mapped to the static pools. You should check you mapfile in your project to be sure, malloc and free are not used anymore.
Please note: Mapping of realloc is currently not supported, because the stdlib.h function just needs pointer and new size as arguments, but RiCAllocator_reallocMemory expects three arguments: the pointer, current size and new size. Also calloc is not being mapped.
If you want to work with NO_MALLOC defined but need to deactivate the mapping of malloc() and free(), make sure to define the macro WST_DO_NOT_MAP_MALLOC.


Copyright (c) Willert Software Tools GmbH. All rights reserved.