Saving RAM by declaring thread functions "noreturn"

One of the problems, when writing embedded multi-threaded applications, is that the thread functions do save the registers in the function entry code even if the system does not require it, exiting such a function would terminate the thread so there is no need to preserve the register values, this can waste tens of bytes for each thread.

The problem

Consider the following code:

#include <ch.h>
 
static WORKING_AREA(waMyThread, 64);
 
static t_msg MyThread(void *arg) {
  while (!chThdShoudTerminate()) {
    /* Do thread inner work */
  }
  return 1;
}
 
main() {
  chSysInit();
  ...
  chThdCreateStatic(waMyThread, sizeof(waMyThread), NORMALPRIO, MyThread, NULL);
  ...
}

The resulting ASM code for the thread function would be something like this:

MyThread:
        stmfd   sp!, {r4, r5, r6, lr}
        ...
        ldmfd   sp!, {r4, r5, r6, pc}

Being that function a thread there is no need to save those registers, in embedded applications often the RAM is a scarce resource.

The solution

Stack space can be saved by modifying the code as follow, using an useful GCC extensions:

#include <ch.h>
 
static WORKING_AREA(waMyThread, 64);
 
__attribute__((noreturn))
static void MyThread(void *arg) {
  while (!chThdShoudTerminate()) {
    /* Do thread inner work */
  }
  chThdExit(1);
}
 
main() {
  chSysInit();
  ...
  chThdCreateStatic(waMyThread, sizeof(waMyThread), NORMALPRIO,
                    (tfunc_t)MyThread, NULL);
  ...
}

This will make GCC believe that the function cannot return and there is no need to save registers. The code will be a bit less readable and less portable on other compilers however.

 
chibios/kb/saveram.txt · Last modified: 2011/10/03 20:57 by giovanni
 
Except where otherwise noted, content on this wiki is licensed under the following license:GNU Free Documentation License 1.3