Changeset 3bb342ca in rtems


Ignore:
Timestamp:
Jul 17, 2015, 9:55:51 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
9154c3f9
Parents:
b56ddbb
git-author:
Sebastian Huber <sebastian.huber@…> (07/17/15 09:55:51)
git-committer:
Sebastian Huber <sebastian.huber@…> (07/17/15 09:57:08)
Message:

doc: Clarify interrupts disable problems on SMP

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/smp.t

    rb56ddbb r3bb342ca  
    238238the use of binary semaphores or mutexes to implement critical sections.
    239239
    240 @subsubsection Disable Interrupts
    241 
    242 Again on a uniprocessor system, there is only a single processor which
    243 logically executes a single task and takes interrupts. On an SMP system,
    244 each processor may take an interrupt. When the application disables
    245 interrupts, it generally does so by altering a processor register to
    246 mask interrupts and later to re-enable them. On a uniprocessor system,
    247 changing this in the single processor is sufficient. However, on an SMP
    248 system, this register in @strong{ALL} processors must be changed. There
    249 are no comparable capabilities in an SMP system to disable all interrupts
    250 across all processors.
     240@subsubsection Disable Interrupts and Interrupt Locks
     241
     242A low overhead means to ensure mutual exclusion in uni-processor configurations
     243is to disable interrupts around a critical section.  This is commonly used in
     244device driver code and throughout the operating system core.  On SMP
     245configurations, however, disabling the interrupts on one processor has no
     246effect on other processors.  So, this is insufficient to ensure system wide
     247mutual exclusion.  The macros
     248@itemize @bullet
     249@item @code{rtems_interrupt_disable()},
     250@item @code{rtems_interrupt_enable()}, and
     251@item @code{rtems_interrupt_flush()}
     252@end itemize
     253are disabled on SMP configurations and its use will lead to compiler warnings
     254and linker errors.  In the unlikely case that interrupts must be disabled on
     255the current processor, then the
     256@itemize @bullet
     257@item @code{rtems_interrupt_local_disable()}, and
     258@item @code{rtems_interrupt_local_enable()}
     259@end itemize
     260macros are now available in all configurations.
     261
     262Since disabling of interrupts is not enough to ensure system wide mutual
     263exclusion on SMP, a new low-level synchronization primitive was added - the
     264interrupt locks.  They are a simple API layer on top of the SMP locks used for
     265low-level synchronization in the operating system core.  Currently they are
     266implemented as a ticket lock.  On uni-processor configurations they degenerate
     267to simple interrupt disable/enable sequences.  It is disallowed to acquire a
     268single interrupt lock in a nested way.  This will result in an infinite loop
     269with interrupts disabled.  While converting legacy code to interrupt locks care
     270must be taken to avoid this situation.
     271
     272@example
     273@group
     274void legacy_code_with_interrupt_disable_enable( void )
     275@{
     276  rtems_interrupt_level level;
     277
     278  rtems_interrupt_disable( level );
     279  /* Some critical stuff */
     280  rtems_interrupt_enable( level );
     281@}
     282
     283RTEMS_INTERRUPT_LOCK_DEFINE( static, lock, "Name" )
     284
     285void smp_ready_code_with_interrupt_lock( void )
     286@{
     287  rtems_interrupt_lock_context lock_context;
     288
     289  rtems_interrupt_lock_acquire( &lock, &lock_context );
     290  /* Some critical stuff */
     291  rtems_interrupt_lock_release( &lock, &lock_context );
     292@}
     293@end group
     294@end example
     295
     296The @code{rtems_interrupt_lock} structure is empty on uni-processor
     297configurations.  Empty structures have a different size in C
     298(implementation-defined, zero in case of GCC) and C++ (implementation-defined
     299non-zero value, one in case of GCC).  Thus the
     300@code{RTEMS_INTERRUPT_LOCK_DECLARE()}, @code{RTEMS_INTERRUPT_LOCK_DEFINE()},
     301@code{RTEMS_INTERRUPT_LOCK_MEMBER()}, and
     302@code{RTEMS_INTERRUPT_LOCK_REFERENCE()} macros are provided to ensure ABI
     303compatibility.
    251304
    252305@subsubsection Highest Priority Task Assumption
Note: See TracChangeset for help on using the changeset viewer.