[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