aboutsummaryrefslogtreecommitdiffstats
path: root/docs/src/mutualexcl.dox
diff options
context:
space:
mode:
Diffstat (limited to 'docs/src/mutualexcl.dox')
-rw-r--r--docs/src/mutualexcl.dox213
1 files changed, 213 insertions, 0 deletions
diff --git a/docs/src/mutualexcl.dox b/docs/src/mutualexcl.dox
new file mode 100644
index 000000000..367618d5d
--- /dev/null
+++ b/docs/src/mutualexcl.dox
@@ -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.
+ * .
+ */
+/** @} */