git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@752 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-02-11 19:37:57 +00:00
parent 1c1d5129c5
commit 50bebb2976
7 changed files with 323 additions and 19 deletions

View File

@ -46,16 +46,10 @@
* - 128 priority levels. * - 128 priority levels.
* - Multiple threads at the same priority level allowed. * - Multiple threads at the same priority level allowed.
* - Round robin scheduling for threads at the same priority level. * - Round robin scheduling for threads at the same priority level.
* - Unlimited number of threads. * - Offers threads, virtual timers, semaphores, mutexes, condvars,
* - Unlimited number of virtual timers. * event flags, messages, I/O queues.
* - Unlimited number of semaphores.
* - Unlimited number of mutexes.
* - Unlimited number of condvars.
* - Unlimited number of event sources.
* - Unlimited number of messages in queue.
* - Unlimited number of I/O queues.
* - No static setup at compile time, there is no need to configure a maximum * - No static setup at compile time, there is no need to configure a maximum
* number of all the above resources. * number of all the above objects.
* - No *need* for a memory allocator, all the kernel structures are static * - No *need* for a memory allocator, all the kernel structures are static
* and declaratively allocated. * and declaratively allocated.
* - Threads, Semaphores, Event Sources, Virtual Timers creation/deletion at * - Threads, Semaphores, Event Sources, Virtual Timers creation/deletion at
@ -73,6 +67,7 @@
* . * .
* <h2>Related pages</h2> * <h2>Related pages</h2>
* - @subpage lic_faq * - @subpage lic_faq
* - @subpage goals
* - @subpage concepts * - @subpage concepts
* - @subpage articles * - @subpage articles
* . * .

View File

@ -21,12 +21,13 @@
* @page articles Articles * @page articles Articles
* @{ * @{
* ChibiOS/RT Articles and Code Examples: * ChibiOS/RT Articles and Code Examples:
* - @subpage article_portguide * - @subpage article_mutual_exclusion
* - @subpage article_atomic * - @subpage article_atomic
* - @subpage article_saveram * - @subpage article_saveram
* - @subpage article_interrupts * - @subpage article_interrupts
* - @subpage article_jitter * - @subpage article_jitter
* - @subpage article_timing * - @subpage article_timing
* - @subpage article_portguide
* . * .
*/ */
/** @} */ /** @} */

88
docs/src/goals.dox Normal file
View File

@ -0,0 +1,88 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/**
* @page goals Project Goals
* @{
* <h2>Another RTOS?</h2>
* The first question to be answered is: there was really the need for YET
* ANOTHER RTOS?<br>
* My answer is yes because various reasons:
* - The ChibiOS/RT ancestor was created more than 15 years ago and while it
* had far less features than the current product it was complete and
* functioning. ChibiOS/RT is just a new (and silly) name given to
* something created when there were not many free RTOSes around (actually
* none, at least none in my knowledge, there was no widespread Internet
* at that time).
* - When, after a while, I needed a RTOS again, none of the existing FOSS
* projects met my expectations or my ideas of how a RTOS should be, not
* even close (see below). I decided that work on that old project was
* a better idea that contribute to, or fork, something else.
* - I wanted another toy.
* .
* <h2>Why is it different?</h2>
* In itself it implements ideas already seen in other projects but never
* all together in a single FOSS project. There are some basic choices in
* ChibiOS/RT (mostly derived by its ancestor):
*
* <h3>Static design</h3>
* Everything in the kernel is static, nowhere memory is allocated or freed,
* there are two allocator subsystems but those are options and not part of
* core OS. Safety is something you design in, not something you can add later.
*
* <h3>No fixed size tables or structures</h3>
* No tables to configure, no arrays that can be filled and overflow at
* runtime. Everything without practical upper bounds (except for resource
* limits and numerical upper bounds of course).
*
* <h3>No error conditions and no error checks</h3>
* All the API should not have error conditions, all the previous points are
* finalized to this objective. Everything you can invoke in the kernel is
* designed to not fail unless you pass garbage as parameters, stray pointers
* or such. Also the APIs are not slowed down by error checks, error checks
* exists but only when the debug switch is activated.<br>
* All the static core APIs always succeed if correct parameters are passed.
*
* <h3>Very simple APIs</h3>
* Every API should have the parameters you would expect for that function, no
* more no less. Each API should do a single thing with no options.
*
* <h3>Damn fast and compact</h3>
* Note first "fast" then "compact", the focus is on speed and execution
* efficiency rather than code size. This does not mean it is large, the OS
* with all the subsystems activated is well below 8KiB (32bit ARM code, the
* least space efficient) and can shrink down below 2KiB. It would be
* possible to make something smaller but:
* -# It would be pointless, it @a is already small.
* -# I would not sacrifice efficiency or features in order to save few bytes.
* .
* About the "fast" part, it is able to start/wait/exit more than <b>200,000
* threads per second</b> on a 72MHz STM32 (Cortex-M3). The Context Switch just
* takes <b>2.3 microseconds</b> on the same STM32. The numbers are not
* pulled out of thin air, it is the output of the included test suite.
*
* <h3>Tests and metrics</h3>
* I think it is nice to know how an OS is tested and how it performs before
* committing to use it. Test results on all the supported platforms and
* performance metrics are included in each ChibiOS/RT release. The test
* code is released as well, all the included demos are capable of executing
* the test suite and the OS benchmarks.
*/
/** @} */

213
docs/src/mutualexcl.dox Normal file
View File

@ -0,0 +1,213 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/**
* @page article_mutual_exclusion Mutual Exclusion guide
* @{
* The most common problem when writing multithreaded code is the
* synchronization on the shared resources/services.<br>
* ChibiOS/RT offers a rich variety of mechanisms that apparently solve the
* same problem. I wrote apparently because each mechanism has its pro and
* cons.
* This article will introduce the various mechanisms and the explain the
* right scenarios for each one.
*
* <h2>Basics</h2>
* Some of the concepts mentioned in this article can be found in the
* following Wikipedia articles:
* - <a href="http://en.wikipedia.org/wiki/Mutual_exclusion" target="_blank">
* Mutual Exclusion</a>
* - <a href="http://en.wikipedia.org/wiki/Priority_inversion" target="_blank">
* Priority Inversion</a>
* - <a href="http://en.wikipedia.org/wiki/Priority_inheritance"
* target="_blank">Priority Inheritance</a>
* - <a href="http://en.wikipedia.org/wiki/Priority_ceiling" target="_blank">
* Priority Ceiling</a>
* .
* <h2>Mutual exclusion by System Locks</h2>
* This is the lowest level mechanism, the system is locked by invoking the
* @p chSysLock() API and then unlocked by invoking @p chSysUnlock().<br>
* The implementation is architecture dependent but it is guaranteed to, at
* least, disable the interrupt sources with hardware priority below or equal
* the kernel level.
*
* <h3>Advantages</h3>
* - It is the lightest as execution time, often a lock or unlock becomes just a
* single inlined assembler instruction.
* - It ensures mutual exclusion among threads but also interrupt handling code.
* - The implementation would ensure mutual exclusion even on multicore
* architectures where multiple hardware threads are present.
* .
* <h3>Disadvantages</h3>
* - Disabling interrupts for a long period of time can deteriorate the overall
* system response time and/or introduce jitter.
* .
* <h3>When use Locks</h3>
* - When mutual exclusion with interrupt handlers is required.
* - When the operation within the lock zone is very simple and has finite
* time.
* .
* <h3>Example</h3>
* @code
* ...
* chSysLock();
* /* Protected code */
* chSysUnlock();
* ...
* @endcode
*
* <h2>Mutual exclusion by Semaphores</h2>
* In ChibiOS/RT the counting semaphores are mainly meant as a
* synchronization mechanism between interrupt handlers and high level code
* running at thread level. Usually a thread waits on a semaphore that is
* signaled asynchronously by an interrupt handler.<br>
* The semaphores can, however, be used as simple mutexes by initializing
* counter to one.
*
* <h3>Advantages</h3>
* - The semaphores code is "already there" if you use the I/O queues and
* you don't want to enable the mutexes too because space constraints.
* - Semaphores are lighter than mutexes because their queues are FIFO
* ordered and do not have any overhead caused by the priority inheritance
* algorithm.
* - A semaphore takes less RAM than a mutex (12 vs 16 bytes on 32 bit
* architectures).
* .
* <h3>Disadvantages</h3>
* - Semaphore queues are FIFO ordered by default, an option exist to make
* them priority ordered but this can impact I/O performance because
* semaphores are used in I/O queues.
* - Semaphores do not implement the priority inheritance algorithm so the
* priority inversion problem is not mitigated.
* .
* <h3>When use Semaphores</h3>
* - When you don't need queuing by priority nor the priority inheritance
* algorithm.
* - When RAM/ROM space is scarce.
* .
* <h3>Example</h3>
* @code
* static Semaphore sem; /* Semaphore declaration */
* ...
* chSemInit(&sem, 1); /* Semaphore initialization before use */
* ...
* chSemWait(&sem);
* /* Protected code */
* chSemSignal(&sem);
* ...
* @endcode
*
* <h2>Mutual exclusion by Mutexes</h2>
* The mutexes, also known as binary semaphores (we choose to not use this
* terminology to avoid confusion with counting semaphores), are the mechanism
* intended as general solution for the mutual exclusion problem.
*
* <h3>Advantages</h3>
* - Mutexes implement the Priority Inheritance algorithm that is an important
* tool in reducing jitter and improve overall system response time (it is
* not a magic solution, just a tool for the system designer).
* .
* <h3>Disadvantages</h3>
* - Heaviest among all the possible choices. The Priority Inheritance method
* is efficiently implemented but nothing is more efficient than no code at
* all.
* .
* <h3>When use Mutexes</h3>
* - When you are designing a very complex system with hard realtime
* requirements.
* .
* <h3>Example</h3>
* @code
* static Mutex mtx; /* Mutex declaration */
* ...
* chMtxInit(&mtx); /* Mutex initialization before use */
* ...
* chMtxLock(&mtx);
* /* Protected code */
* chMtxUnlock();
* ...
* @endcode
*
* <h2>Mutual exclusion by priority boost</h2>
* Another way to implement mutual exclusion is to boost the thread priority
* to a level higher than all of the threads competing for a certain resource.
* This solution effectively implements an Immediate Priority Ceiling
* algorithm.
*
* <h3>Advantages</h3>
* - Almost free as code size, you need no semaphores nor mutexes.
* - No RAM overhead.
* - Fast execution, priority change is a quick operation under ChibiOS/RT.
* - The priority ceiling protocol that can help mitigate the Priority
* Inversion problem.
* .
* <h3>Disadvantages</h3>
* - Makes the design more complicated because priorities must be assigned to
* not just threads but also assigned to the resources to be protected.
* - Locking a resource affects all the threads with lower priority even if
* not interested to the resource.
* - All the threads that can access the resource must have lower priority
* than the resource itself.
* - The mechanism is not easy to understand in the code unless it is clearly
* documented.
* - This method does not work in on multicore architectures where multiple
* hardware threads are present.
* - Only useful in very simple applications.
* .
* <h3>Example</h3>
* @code
* /* Priority assigned to the resource, threads must have lower
* priority than this.*/
* #define AAA_RESOURCE_PRIORITY NORMALPRIO+10
* ...
* /* Locks the resources AAA.*/
* tprio_t aaa_old_prio = chThdSetPriority(AAA_RESOURCE_PRIORITY);
* /* Accessing resource AAA */
* chThdSetPriority(aaa_old_prio); /* Unlocks AAA.*/
* ...
* @endcode
*
* <h2>Mutual exclusion by message passing</h2>
* Another method is to make a single dedicated thread execute the critical
* code and make it work as a messages server. The other threads can request
* the service to the server by sending a properly formatted message and
* then wait for the answer with the result.<br>
* This method is very useful when integrating into the system components not
* designed to be reentrant or to be executed in a multithreaded environment,
* as example a 3rd part file system or a networking protocol stack.
*
* <h3>Advantages</h3>
* - It is possible to encapsulate very complex logic without worry about
* about concurrent accesses.
* - If the encapsulate code uses a large stack area only the server thread
* have to allocate enough RAM, the client threads save RAM by just
* requesting the service to the server.
* - Clean system architecture.
* - This method also implements a form of Priority Ceiling. The ceiling is
* the priority of the server thread itself.
* .
* <h3>Disadvantages</h3>
* - More complex implementation, a protocol must be created between clients
* and server.
* - Two context switches are required for each request to the server (but
* ChibiOSRT is very efficient at that).
* - Requires a dedicated thread.
* .
*/
/** @} */

View File

@ -108,6 +108,8 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process,
registers usage now the kernel is much smaller, faster and most OS APIs registers usage now the kernel is much smaller, faster and most OS APIs
use less RAM in stack frames (note, this is an ARM7 thumb mode specific use less RAM in stack frames (note, this is an ARM7 thumb mode specific
optimization). optimization).
- CHANGE: Now the API chThdSetPriority() returns the old priority instead
of void.
- CHANGE: Modified the signature of the chMsgSendWithEvent() API, it now uses - CHANGE: Modified the signature of the chMsgSendWithEvent() API, it now uses
a more efficient event signaling method. a more efficient event signaling method.
- CHANGE: Removed the field p_tid from the Thread structure and the related - CHANGE: Removed the field p_tid from the Thread structure and the related

View File

@ -189,29 +189,34 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS */ #endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS */
/** /**
* @brief Changes the running thread priority then reschedules if necessary. * @brief Changes the running thread priority level then reschedules if
* necessary.
* *
* @param newprio the new priority of the running thread * @param newprio the new priority level of the running thread
* @return The old priority level.
* @note The function returns the real thread priority regardless of the
* actual priority that could be higher than the real priority because
* the priority inheritance mechanism.
*/ */
void chThdSetPriority(tprio_t newprio) { tprio_t chThdSetPriority(tprio_t newprio) {
tprio_t oldprio;
chDbgAssert(newprio <= HIGHPRIO, "chthreads.c, chThdSetPriority()"); chDbgAssert(newprio <= HIGHPRIO, "chthreads.c, chThdSetPriority()");
chSysLock(); chSysLock();
#if CH_USE_MUTEXES #if CH_USE_MUTEXES
if (currp->p_prio != currp->p_realprio) { oldprio = currp->p_realprio;
if (newprio > currp->p_prio) if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio))
currp->p_prio = newprio;
}
else
currp->p_prio = newprio; currp->p_prio = newprio;
currp->p_realprio = newprio; currp->p_realprio = newprio;
#else #else
oldprio = currp->p_prio;
currp->p_prio = newprio; currp->p_prio = newprio;
#endif #endif
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); chSysUnlock();
return oldprio;
} }
/** /**

View File

@ -172,7 +172,7 @@ extern "C" {
Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio,
tfunc_t pf, void *arg); tfunc_t pf, void *arg);
#endif #endif
void chThdSetPriority(tprio_t newprio); tprio_t chThdSetPriority(tprio_t newprio);
Thread *chThdResume(Thread *tp); Thread *chThdResume(Thread *tp);
void chThdTerminate(Thread *tp); void chThdTerminate(Thread *tp);
void chThdSleep(systime_t time); void chThdSleep(systime_t time);