/*
    ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
    This file is part of ChibiOS/RT.
    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .
*/
/**
 * @page article_saveram 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.
 * Consider the following code: 
 * @code
#include 
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);
  ...
}
 * @endcode
 * The resulting ASM code for the thread function would be something like this:
 * @code
MyThread:
        stmfd   sp!, {r4, r5, r6, lr}
        ...
        ldmfd   sp!, {r4, r5, r6, pc}
 * @endcode
 * Being that function a thread there is no need to save those registers, in
 * embedded applications often the RAM is a scarce resource. That space can be
 * saved by modifying the code as follow, using some advanced GCC extensions: 
 * @code
#include 
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);
  ...
}
 * @endcode
 * 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.
 */