[rtems commit] rtems: Add SMP support for signals

Sebastian Huber sebh at rtems.org
Tue Aug 27 08:44:49 UTC 2013


Module:    rtems
Branch:    master
Commit:    75f6d18ee0a470c092216249ab1dc6f3c5187dea
Changeset: http://git.rtems.org/rtems/commit/?id=75f6d18ee0a470c092216249ab1dc6f3c5187dea

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Aug 26 16:03:35 2013 +0200

rtems: Add SMP support for signals

Add and use _ASR_Get_posted_signals().  The post-switch handler is not
protected by disabled thread dispatching.  Use proper SMP lock for
signal management.

---

 cpukit/rtems/include/rtems/rtems/asr.h     |    3 ++
 cpukit/rtems/include/rtems/rtems/asrimpl.h |   52 ++++++++++++++++++----------
 cpukit/rtems/src/signalcatch.c             |    8 +----
 cpukit/rtems/src/signalsend.c              |    4 +-
 4 files changed, 40 insertions(+), 27 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/asr.h b/cpukit/rtems/include/rtems/rtems/asr.h
index 225b0b9..f543b50 100644
--- a/cpukit/rtems/include/rtems/rtems/asr.h
+++ b/cpukit/rtems/include/rtems/rtems/asr.h
@@ -22,6 +22,7 @@
 #ifndef _RTEMS_RTEMS_ASR_H
 #define _RTEMS_RTEMS_ASR_H
 
+#include <rtems/score/isrlock.h>
 #include <rtems/rtems/modes.h>
 
 #ifdef __cplusplus
@@ -73,6 +74,8 @@ typedef struct {
   rtems_signal_set  signals_pending;
   /** This field indicates if nest level of signals being processed */
   uint32_t          nest_level;
+  /** Lock to protect this structure */
+  ISR_lock_Control  Lock;
 }   ASR_Information;
 
 /*
diff --git a/cpukit/rtems/include/rtems/rtems/asrimpl.h b/cpukit/rtems/include/rtems/rtems/asrimpl.h
index dc7da55..ebb4052 100644
--- a/cpukit/rtems/include/rtems/rtems/asrimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/asrimpl.h
@@ -18,7 +18,6 @@
 #define _RTEMS_RTEMS_ASRIMPL_H
 
 #include <rtems/rtems/asr.h>
-#include <rtems/score/isrlevel.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -38,15 +37,16 @@ extern "C" {
  *  This routine initializes the given RTEMS_ASR information record.
  */
 RTEMS_INLINE_ROUTINE void _ASR_Initialize (
-  ASR_Information *information
+  ASR_Information *asr
 )
 {
-  information->is_enabled      = false;
-  information->handler         = NULL;
-  information->mode_set        = RTEMS_DEFAULT_MODES;
-  information->signals_posted  = 0;
-  information->signals_pending = 0;
-  information->nest_level      = 0;
+  asr->is_enabled      = false;
+  asr->handler         = NULL;
+  asr->mode_set        = RTEMS_DEFAULT_MODES;
+  asr->signals_posted  = 0;
+  asr->signals_pending = 0;
+  asr->nest_level      = 0;
+  _ISR_lock_Initialize( &asr->Lock );
 }
 
 /**
@@ -57,17 +57,17 @@ RTEMS_INLINE_ROUTINE void _ASR_Initialize (
  *  way that the RTEMS_ASR disable/enable flag changes.
  */
 RTEMS_INLINE_ROUTINE void _ASR_Swap_signals (
-  ASR_Information *information
+  ASR_Information *asr
 )
 {
   rtems_signal_set _signals;
   ISR_Level        _level;
 
-  _ISR_Disable( _level );
-    _signals                     = information->signals_pending;
-    information->signals_pending = information->signals_posted;
-    information->signals_posted  = _signals;
-  _ISR_Enable( _level );
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
+    _signals             = asr->signals_pending;
+    asr->signals_pending = asr->signals_posted;
+    asr->signals_posted  = _signals;
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
 }
 
 /**
@@ -90,10 +90,10 @@ RTEMS_INLINE_ROUTINE bool _ASR_Is_null_handler (
  *  given RTEMS_ASR information record and FALSE otherwise.
  */
 RTEMS_INLINE_ROUTINE bool _ASR_Are_signals_pending (
-  ASR_Information *information
+  ASR_Information *asr
 )
 {
-  return information->signals_posted != 0;
+  return asr->signals_posted != 0;
 }
 
 /**
@@ -105,15 +105,31 @@ RTEMS_INLINE_ROUTINE bool _ASR_Are_signals_pending (
  *  NOTE:  This must be implemented as a macro.
  */
 RTEMS_INLINE_ROUTINE void _ASR_Post_signals(
+  ASR_Information  *asr,
   rtems_signal_set  signals,
   rtems_signal_set *signal_set
 )
 {
   ISR_Level              _level;
 
-  _ISR_Disable( _level );
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
     *signal_set |= signals;
-  _ISR_Enable( _level );
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
+}
+
+RTEMS_INLINE_ROUTINE rtems_signal_set _ASR_Get_posted_signals(
+  ASR_Information *asr
+)
+{
+  rtems_signal_set signal_set;
+  ISR_Level        _level;
+
+  _ISR_lock_ISR_disable_and_acquire( &asr->Lock, _level );
+    signal_set = asr->signals_posted;
+    asr->signals_posted = 0;
+  _ISR_lock_Release_and_ISR_enable( &asr->Lock, _level );
+
+  return signal_set;
 }
 
 /**@}*/
diff --git a/cpukit/rtems/src/signalcatch.c b/cpukit/rtems/src/signalcatch.c
index 3493e72..a5e5ef8 100644
--- a/cpukit/rtems/src/signalcatch.c
+++ b/cpukit/rtems/src/signalcatch.c
@@ -27,7 +27,6 @@
 
 static void _RTEMS_signal_Post_switch_hook( Thread_Control *executing )
 {
-  ISR_Level          level;
   RTEMS_API_Control *api;
   ASR_Information   *asr;
   rtems_signal_set   signal_set;
@@ -42,12 +41,7 @@ static void _RTEMS_signal_Post_switch_hook( Thread_Control *executing )
    */
 
   asr = &api->Signal;
-
-  _ISR_Disable( level );
-    signal_set = asr->signals_posted;
-    asr->signals_posted = 0;
-  _ISR_Enable( level );
-
+  signal_set = _ASR_Get_posted_signals( asr );
 
   if ( !signal_set ) /* similar to _ASR_Are_signals_pending( asr ) */
     return;
diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c
index f1c7b2c..c231235 100644
--- a/cpukit/rtems/src/signalsend.c
+++ b/cpukit/rtems/src/signalsend.c
@@ -46,10 +46,10 @@ rtems_status_code rtems_signal_send(
 
       if ( ! _ASR_Is_null_handler( asr->handler ) ) {
         if ( asr->is_enabled ) {
-          _ASR_Post_signals( signal_set, &asr->signals_posted );
+          _ASR_Post_signals( asr, signal_set, &asr->signals_posted );
           _Thread_Signal_notification( the_thread );
         } else {
-          _ASR_Post_signals( signal_set, &asr->signals_pending );
+          _ASR_Post_signals( asr, signal_set, &asr->signals_pending );
         }
         _Objects_Put( &the_thread->Object );
         return RTEMS_SUCCESSFUL;




More information about the vc mailing list