[rtems commit] doc: Clarify interrupts disable problems on SMP
Sebastian Huber
sebh at rtems.org
Fri Jul 17 09:57:23 UTC 2015
Module: rtems
Branch: master
Commit: 3bb342ca92d74547da5ec8d623e56bb3999cdcaa
Changeset: http://git.rtems.org/rtems/commit/?id=3bb342ca92d74547da5ec8d623e56bb3999cdcaa
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Fri Jul 17 11:55:51 2015 +0200
doc: Clarify interrupts disable problems on SMP
---
doc/user/smp.t | 75 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 64 insertions(+), 11 deletions(-)
diff --git a/doc/user/smp.t b/doc/user/smp.t
index 8437269..76eac07 100644
--- a/doc/user/smp.t
+++ b/doc/user/smp.t
@@ -237,17 +237,70 @@ In general, applications must use proper operating system provided mutual
exclusion mechanisms to ensure correct behavior. This primarily means
the use of binary semaphores or mutexes to implement critical sections.
- at subsubsection Disable Interrupts
-
-Again on a uniprocessor system, there is only a single processor which
-logically executes a single task and takes interrupts. On an SMP system,
-each processor may take an interrupt. When the application disables
-interrupts, it generally does so by altering a processor register to
-mask interrupts and later to re-enable them. On a uniprocessor system,
-changing this in the single processor is sufficient. However, on an SMP
-system, this register in @strong{ALL} processors must be changed. There
-are no comparable capabilities in an SMP system to disable all interrupts
-across all processors.
+ at subsubsection Disable Interrupts and Interrupt Locks
+
+A low overhead means to ensure mutual exclusion in uni-processor configurations
+is to disable interrupts around a critical section. This is commonly used in
+device driver code and throughout the operating system core. On SMP
+configurations, however, disabling the interrupts on one processor has no
+effect on other processors. So, this is insufficient to ensure system wide
+mutual exclusion. The macros
+ at itemize @bullet
+ at item @code{rtems_interrupt_disable()},
+ at item @code{rtems_interrupt_enable()}, and
+ at item @code{rtems_interrupt_flush()}
+ at end itemize
+are disabled on SMP configurations and its use will lead to compiler warnings
+and linker errors. In the unlikely case that interrupts must be disabled on
+the current processor, then the
+ at itemize @bullet
+ at item @code{rtems_interrupt_local_disable()}, and
+ at item @code{rtems_interrupt_local_enable()}
+ at end itemize
+macros are now available in all configurations.
+
+Since disabling of interrupts is not enough to ensure system wide mutual
+exclusion on SMP, a new low-level synchronization primitive was added - the
+interrupt locks. They are a simple API layer on top of the SMP locks used for
+low-level synchronization in the operating system core. Currently they are
+implemented as a ticket lock. On uni-processor configurations they degenerate
+to simple interrupt disable/enable sequences. It is disallowed to acquire a
+single interrupt lock in a nested way. This will result in an infinite loop
+with interrupts disabled. While converting legacy code to interrupt locks care
+must be taken to avoid this situation.
+
+ at example
+ at group
+void legacy_code_with_interrupt_disable_enable( void )
+@{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level );
+ /* Some critical stuff */
+ rtems_interrupt_enable( level );
+@}
+
+RTEMS_INTERRUPT_LOCK_DEFINE( static, lock, "Name" )
+
+void smp_ready_code_with_interrupt_lock( void )
+@{
+ rtems_interrupt_lock_context lock_context;
+
+ rtems_interrupt_lock_acquire( &lock, &lock_context );
+ /* Some critical stuff */
+ rtems_interrupt_lock_release( &lock, &lock_context );
+@}
+ at end group
+ at end example
+
+The @code{rtems_interrupt_lock} structure is empty on uni-processor
+configurations. Empty structures have a different size in C
+(implementation-defined, zero in case of GCC) and C++ (implementation-defined
+non-zero value, one in case of GCC). Thus the
+ at code{RTEMS_INTERRUPT_LOCK_DECLARE()}, @code{RTEMS_INTERRUPT_LOCK_DEFINE()},
+ at code{RTEMS_INTERRUPT_LOCK_MEMBER()}, and
+ at code{RTEMS_INTERRUPT_LOCK_REFERENCE()} macros are provided to ensure ABI
+compatibility.
@subsubsection Highest Priority Task Assumption
More information about the vc
mailing list