Stack Management in RTOSes

Proper size of the stack is important. It must be small enough to prevent memory wastage and large enough to accommodate real-time application requirements.

The ways to determine the size to allocate are-

  • Test the system under conditions that produce worst-case stack behavior – hard to predict/provoke.

  • Calculate the theoretical maximum stack requirement (using software tools).

Browsing for stack sizes through the Dalvik source history:

API 3 (Android 1.5) = 8KB

API 4-10 (Android 1.6 – Android 2.3.7) = 12KB

API 14-17 (Android 4.0 – Android 4.2.2) = 16KB

Garbage collection on the stack – The life span of variables on the stack is limited to the duration of the function. As soon as the function returns, the used stack memory will be freed.

Multi-Task Stack Sharing (MTSS) scheme

MTSS is a multi-task stack sharing technique, that grows the stack of a particular task into other tasks in the system after it has overflown its bounds. A possible configuration to use MTSS effectively is to deliberately reduce the memory provided to each task to below what it needs, and the deficit is recovered from stacks of other tasks. It helps to reduce the physical memory needed for an embedded system without reducing its reliability.

The advantages of this technique are-

  • This technique can avoid the out-of-memory error if the extra space recovered is enough to complete execution. This increases system reliability.

  • MTSS can also be used for decreasing the physical memory for an embedded system by reducing the initial memory allocated to each of the tasks and recovering the deficit by sharing stack with other tasks, reducing the memory cost/footprint of the system.

  • MTSS also offers good real time guarantees, since it uses a paging system that never incurs an episodic increase in run-time. Due to fixed size page allocation, the overhead is spread out over the program, with a small overhead every time a page overflows. Every time the stack overflows, one fixed size page is allocated from a list of free pages, which incurs the same cost throughout the execution of program.

  • Very little run-time overhead in the common case when no stack in the system overflows, because only the compile time check for overflow is executed on every procedure entry and return. A task grows in its own native stack until it runs out of space there; thus additional run-time is only incurred on an overflow. The run-time and code size overheads are 1.8% and 2.6% on an average.

Tasks are unlikely to need their maximum stack space at the same instant of time. Thus when one task overflows, it is quite likely that the stacks of other tasks have substantial free space in them. Normally this space cannot be used for the overflowing stack since it is not contiguous with it. So this free space can be used by growing the overflowing stack discontiguously in that space. If successful, the overflow will be postponed and hopefully avoided, thus increasing system reliability.

MTSS is built on top of cactus stack layout. Wasted space is recovered using an innovative paging system –

  1. Compile time checks are inserted at the beginning of each procedure which check for stack overflow.

  2. if an overflow is detected, then a fixed size block of memory, called a page, is allocated in the free space of one of the other tasks that has such free space.
    The page is allocated in the stack space at the far end from the direction of stack growth so that the chance that the native stack in that space will itself overflow is reduced. If multiple tasks have free pages, then the task with the least number of already allocated overflow pages is selected for discontiguous growth of the overflowing stack.

  3. If the current overflow page(s) is also filled, additional page(s) are allocated using the same scheme.

  4. Compile time checks are inserted at each procedure return, to check if the overflowing stack has withdrawn from the page. In that case, that page is released back to the free list of pages.

Leave a comment