diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2006-03-07 20:47:53 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2006-03-07 20:47:53 +0000 |
commit | f0ad529d28688214568532c0d30eb13654db1462 (patch) | |
tree | 0b254b2a26f754f598edf2b441c2ebd7576666ea /cpukit | |
parent | New. (diff) | |
download | rtems-f0ad529d28688214568532c0d30eb13654db1462.tar.bz2 |
2006-03-07 Joel Sherrill <joel@OARcorp.com>
PR 866/rtems
* score/include/rtems/system.h, score/include/rtems/score/isr.h,
score/inline/rtems/score/thread.inl,
score/macros/rtems/score/thread.inl: Added memory barriers to enter
and exit of dispatching and interrupt critical sections so GCC will
not optimize and reorder code out of a critical section.
Diffstat (limited to '')
-rw-r--r-- | cpukit/ChangeLog | 9 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/isr.h | 16 | ||||
-rw-r--r-- | cpukit/score/include/rtems/system.h | 11 | ||||
-rw-r--r-- | cpukit/score/inline/rtems/score/thread.inl | 3 | ||||
-rw-r--r-- | cpukit/score/macros/rtems/score/thread.inl | 18 |
5 files changed, 49 insertions, 8 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 6b871c3776..66337501f9 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,12 @@ +2006-03-07 Joel Sherrill <joel@OARcorp.com> + + PR 866/rtems + * score/include/rtems/system.h, score/include/rtems/score/isr.h, + score/inline/rtems/score/thread.inl, + score/macros/rtems/score/thread.inl: Added memory barriers to enter + and exit of dispatching and interrupt critical sections so GCC will + not optimize and reorder code out of a critical section. + 2006-02-08 Thomas Rauscher <trauscher@loytec.com> PR 890/networking diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h index 320332dfd7..1359e91fd8 100644 --- a/cpukit/score/include/rtems/score/isr.h +++ b/cpukit/score/include/rtems/score/isr.h @@ -104,7 +104,10 @@ void _ISR_Handler_initialization ( void ); * the argument _level will contain the previous interrupt mask level. */ #define _ISR_Disable( _level ) \ - _CPU_ISR_Disable( _level ) + do { \ + _CPU_ISR_Disable( _level ); \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + } while (0) /** * This routine enables interrupts to the previous interrupt mask @@ -112,7 +115,10 @@ void _ISR_Handler_initialization ( void ); * enable interrupts so they can be processed again. */ #define _ISR_Enable( _level ) \ - _CPU_ISR_Enable( _level ) + do { \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + _CPU_ISR_Enable( _level ); \ + } while (0) /** * This routine temporarily enables interrupts to the previous @@ -127,7 +133,11 @@ void _ISR_Handler_initialization ( void ); * properly protects itself. */ #define _ISR_Flash( _level ) \ - _CPU_ISR_Flash( _level ) + do { \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + _CPU_ISR_Flash( _level ); \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + } while (0) /** * This routine installs new_handler as the interrupt service routine diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h index 59d5b293af..9558155daf 100644 --- a/cpukit/score/include/rtems/system.h +++ b/cpukit/score/include/rtems/system.h @@ -135,6 +135,17 @@ extern "C" { # define RTEMS_INLINE_ROUTINE #endif +/** + * The following macro is a compiler specific way to ensure that memory + * writes are not reordered around certian points. This specifically can + * impact interrupt disable and thread dispatching critical sections. + */ +#ifdef __GNUC__ + #define RTEMS_COMPILER_MEMORY_BARRIER() asm volatile("" ::: "memory") +#else + #define RTEMS_COMPILER_MEMORY_BARRIER() +#endif + #ifdef RTEMS_POSIX_API /** The following is used by the POSIX implementation to catch bad paths. */ int POSIX_MP_NOT_IMPLEMENTED( void ); diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl index 1599883d70..125f7cf5f7 100644 --- a/cpukit/score/inline/rtems/score/thread.inl +++ b/cpukit/score/inline/rtems/score/thread.inl @@ -142,6 +142,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void ) RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void ) { _Thread_Dispatch_disable_level += 1; + RTEMS_COMPILER_MEMORY_BARRIER(); } /** @@ -154,6 +155,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Disable_dispatch( void ) #if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) RTEMS_INLINE_ROUTINE void _Thread_Enable_dispatch() { + RTEMS_COMPILER_MEMORY_BARRIER(); if ( (--_Thread_Dispatch_disable_level) == 0 ) _Thread_Dispatch(); } @@ -171,6 +173,7 @@ void _Thread_Enable_dispatch( void ); RTEMS_INLINE_ROUTINE void _Thread_Unnest_dispatch( void ) { + RTEMS_COMPILER_MEMORY_BARRIER(); _Thread_Dispatch_disable_level -= 1; } diff --git a/cpukit/score/macros/rtems/score/thread.inl b/cpukit/score/macros/rtems/score/thread.inl index b5b94799c8..3ace7af4e2 100644 --- a/cpukit/score/macros/rtems/score/thread.inl +++ b/cpukit/score/macros/rtems/score/thread.inl @@ -126,7 +126,10 @@ */ #define _Thread_Disable_dispatch() \ - _Thread_Dispatch_disable_level += 1 + do { \ + _Thread_Dispatch_disable_level += 1; \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + } while (0) /*PAGE * @@ -136,9 +139,11 @@ #if ( CPU_INLINE_ENABLE_DISPATCH == TRUE ) #define _Thread_Enable_dispatch() \ - { if ( (--_Thread_Dispatch_disable_level) == 0 ) \ - _Thread_Dispatch(); \ - } + do { \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + if ( (--_Thread_Dispatch_disable_level) == 0 ) \ + _Thread_Dispatch(); \ + } while (0) #endif #if ( CPU_INLINE_ENABLE_DISPATCH == FALSE ) @@ -152,7 +157,10 @@ void _Thread_Enable_dispatch( void ); */ #define _Thread_Unnest_dispatch() \ - _Thread_Dispatch_disable_level -= 1 + do { \ + RTEMS_COMPILER_MEMORY_BARRIER(); \ + _Thread_Dispatch_disable_level -= 1; \ + } while (0) /*PAGE * |