summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2006-03-07 20:47:24 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2006-03-07 20:47:24 +0000
commit3d34e70fc27dff82578c3da7325bab57f69d318f (patch)
treec05eda407ca5a4ed20905135ea23bec1f6c6cbbf
parent2006-03-07 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-3d34e70fc27dff82578c3da7325bab57f69d318f.tar.bz2
2006-03-07 Joel Sherrill <joel@OARcorp.com>
PR 866/rtems * include/rtems/system.h, include/rtems/score/isr.h, inline/rtems/score/thread.inl, 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.
-rw-r--r--cpukit/score/ChangeLog9
-rw-r--r--cpukit/score/include/rtems/score/isr.h16
-rw-r--r--cpukit/score/include/rtems/system.h11
-rw-r--r--cpukit/score/inline/rtems/score/thread.inl3
-rw-r--r--cpukit/score/macros/rtems/score/thread.inl18
5 files changed, 49 insertions, 8 deletions
diff --git a/cpukit/score/ChangeLog b/cpukit/score/ChangeLog
index aea807b6d0..a8de148d84 100644
--- a/cpukit/score/ChangeLog
+++ b/cpukit/score/ChangeLog
@@ -1,3 +1,12 @@
+2006-03-07 Joel Sherrill <joel@OARcorp.com>
+
+ PR 866/rtems
+ * include/rtems/system.h, include/rtems/score/isr.h,
+ inline/rtems/score/thread.inl, 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.
+
2005-09-01 Joel Sherrill <joel@OARcorp.com>
PR 820/rtems
diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h
index 2e46117294..a097ccdae0 100644
--- a/cpukit/score/include/rtems/score/isr.h
+++ b/cpukit/score/include/rtems/score/isr.h
@@ -111,7 +111,10 @@ void _ISR_Handler_initialization ( void );
*/
#define _ISR_Disable( _level ) \
- _CPU_ISR_Disable( _level )
+ do { \
+ _CPU_ISR_Disable( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
/*
* _ISR_Enable
@@ -124,7 +127,10 @@ void _ISR_Handler_initialization ( void );
*/
#define _ISR_Enable( _level ) \
- _CPU_ISR_Enable( _level )
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Enable( _level ); \
+ } while (0)
/*
* _ISR_Flash
@@ -144,7 +150,11 @@ void _ISR_Handler_initialization ( void );
*/
#define _ISR_Flash( _level ) \
- _CPU_ISR_Flash( _level )
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Flash( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
/*
* _ISR_Install_vector
diff --git a/cpukit/score/include/rtems/system.h b/cpukit/score/include/rtems/system.h
index 22895adb25..6f3f04ec29 100644
--- a/cpukit/score/include/rtems/system.h
+++ b/cpukit/score/include/rtems/system.h
@@ -102,6 +102,17 @@ extern "C" {
#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
+
+/*
* The following are used by the POSIX implementation to catch bad paths.
*/
diff --git a/cpukit/score/inline/rtems/score/thread.inl b/cpukit/score/inline/rtems/score/thread.inl
index 1154c061d2..5e7729e7c8 100644
--- a/cpukit/score/inline/rtems/score/thread.inl
+++ b/cpukit/score/inline/rtems/score/thread.inl
@@ -184,6 +184,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();
}
/*PAGE
@@ -201,6 +202,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();
}
@@ -223,6 +225,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 090552e845..1ae1310254 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
*