[rtems commit] posix: Add and use _POSIX_signals_Acquire()

Sebastian Huber sebh at rtems.org
Tue Aug 27 10:45:34 UTC 2013


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Aug 26 17:39:00 2013 +0200

posix: Add and use _POSIX_signals_Acquire()

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

---

 cpukit/posix/include/rtems/posix/psignalimpl.h |   12 +++++++++++-
 cpukit/posix/src/psignal.c                     |    8 +++++---
 cpukit/posix/src/psignalchecksignal.c          |    2 +-
 cpukit/posix/src/psignalclearsignals.c         |   14 +++++++++++---
 cpukit/posix/src/psignalsetprocesssignals.c    |    4 ++--
 cpukit/posix/src/sigtimedwait.c                |   20 ++++++++++++++------
 testsuites/psxtests/psxsignal05/init.c         |    3 ++-
 7 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/psignalimpl.h b/cpukit/posix/include/rtems/posix/psignalimpl.h
index 2dd1ed6..c496fd3 100644
--- a/cpukit/posix/include/rtems/posix/psignalimpl.h
+++ b/cpukit/posix/include/rtems/posix/psignalimpl.h
@@ -32,6 +32,7 @@
 #include <rtems/posix/pthread.h>
 #include <rtems/posix/sigset.h>
 #include <rtems/score/apiext.h>
+#include <rtems/score/isrlock.h>
 #include <rtems/score/threadq.h>
 
 #define _States_Is_interruptible_signal( _states ) \
@@ -54,6 +55,8 @@
  *  Variables
  */
 
+extern ISR_lock_Control _POSIX_signals_Lock;
+
 extern sigset_t  _POSIX_signals_Pending;
 
 extern const struct sigaction _POSIX_signals_Default_vectors[ SIG_ARRAY_MAX ];
@@ -77,6 +80,12 @@ extern API_extensions_Post_switch_control _POSIX_signals_Post_switch;
  */
 void _POSIX_signals_Manager_Initialization(void);
 
+#define _POSIX_signals_Acquire( level ) \
+  _ISR_lock_ISR_disable_and_acquire( &_POSIX_signals_Lock, level )
+
+#define _POSIX_signals_Release( level ) \
+  _ISR_lock_Release_and_ISR_enable( &_POSIX_signals_Lock, level )
+
 static inline void _POSIX_signals_Add_post_switch_extension(void)
 {
   _API_extensions_Add_post_switch( &_POSIX_signals_Post_switch );
@@ -110,7 +119,8 @@ bool _POSIX_signals_Clear_signals(
   int                 signo,
   siginfo_t          *info,
   bool                is_global,
-  bool                check_blocked
+  bool                check_blocked,
+  bool                do_signals_acquire_release
 );
 
 int killinfo(
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index 1778cec..5258b2b 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -45,6 +45,8 @@ RTEMS_STATIC_ASSERT(
 
 /*** PROCESS WIDE STUFF ****/
 
+ISR_lock_Control _POSIX_signals_Lock = ISR_LOCK_INITIALIZER;
+
 sigset_t  _POSIX_signals_Pending;
 
 void _POSIX_signals_Abnormal_termination_handler(
@@ -144,13 +146,13 @@ static void _POSIX_signals_Post_switch_hook(
    *  processed at all.  No point in doing this loop otherwise.
    */
   while (1) {
-    _ISR_Disable( level );
+    _POSIX_signals_Acquire( level );
       if ( !(~api->signals_blocked &
             (api->signals_pending | _POSIX_signals_Pending)) ) {
-       _ISR_Enable( level );
+       _POSIX_signals_Release( level );
        break;
      }
-    _ISR_Enable( level );
+    _POSIX_signals_Release( level );
 
     for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) {
       _POSIX_signals_Check_signal( api, signo, false );
diff --git a/cpukit/posix/src/psignalchecksignal.c b/cpukit/posix/src/psignalchecksignal.c
index cb3703e..468fd62 100644
--- a/cpukit/posix/src/psignalchecksignal.c
+++ b/cpukit/posix/src/psignalchecksignal.c
@@ -49,7 +49,7 @@ bool    _POSIX_signals_Check_signal(
   Thread_Control             *executing;
 
   if ( ! _POSIX_signals_Clear_signals( api, signo, &siginfo_struct,
-                                       is_global, true ) )
+                                       is_global, true, true ) )
     return false;
 
   /*
diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c
index 389c335..88de41c 100644
--- a/cpukit/posix/src/psignalclearsignals.c
+++ b/cpukit/posix/src/psignalclearsignals.c
@@ -42,7 +42,8 @@ bool _POSIX_signals_Clear_signals(
   int                 signo,
   siginfo_t          *info,
   bool                is_global,
-  bool                check_blocked
+  bool                check_blocked,
+  bool                do_signals_acquire_release
 )
 {
   sigset_t                    mask;
@@ -67,7 +68,10 @@ bool _POSIX_signals_Clear_signals(
   /* XXX is this right for siginfo type signals? */
   /* XXX are we sure they can be cleared the same way? */
 
-  _ISR_Disable( level );
+  if ( do_signals_acquire_release ) {
+    _POSIX_signals_Acquire( level );
+  }
+
     if ( is_global ) {
        if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
          if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
@@ -97,6 +101,10 @@ bool _POSIX_signals_Clear_signals(
         do_callout = true;
       }
     }
-  _ISR_Enable( level );
+
+  if ( do_signals_acquire_release ) {
+    _POSIX_signals_Release( level );
+  }
+
   return do_callout;
 }
diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c
index 3ad1c8a..9cce233 100644
--- a/cpukit/posix/src/psignalsetprocesssignals.c
+++ b/cpukit/posix/src/psignalsetprocesssignals.c
@@ -39,7 +39,7 @@ void _POSIX_signals_Set_process_signals(
 {
   ISR_Level  level;
 
-  _ISR_Disable( level );
+  _POSIX_signals_Acquire( level );
     _POSIX_signals_Pending |= mask;
-  _ISR_Enable( level );
+  _POSIX_signals_Release( level );
 }
diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c
index 65454ac..a7fbc1f 100644
--- a/cpukit/posix/src/sigtimedwait.c
+++ b/cpukit/posix/src/sigtimedwait.c
@@ -117,7 +117,7 @@ int sigtimedwait(
 
   /* API signals pending? */
 
-  _ISR_Disable( level );
+  _POSIX_signals_Acquire( level );
   if ( *set & api->signals_pending ) {
     /* XXX real info later */
     the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending );
@@ -126,9 +126,10 @@ int sigtimedwait(
       the_info->si_signo,
       the_info,
       false,
+      false,
       false
     );
-    _ISR_Enable( level );
+    _POSIX_signals_Release( level );
 
     the_info->si_code = SI_USER;
     the_info->si_value.sival_int = 0;
@@ -139,8 +140,8 @@ int sigtimedwait(
 
   if ( *set & _POSIX_signals_Pending ) {
     signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending );
-    _POSIX_signals_Clear_signals( api, signo, the_info, true, false );
-    _ISR_Enable( level );
+    _POSIX_signals_Clear_signals( api, signo, the_info, true, false, false );
+    _POSIX_signals_Release( level );
 
     the_info->si_signo = signo;
     the_info->si_code = SI_USER;
@@ -156,7 +157,7 @@ int sigtimedwait(
     executing->Wait.option          = *set;
     executing->Wait.return_argument = the_info;
     _Thread_queue_Enter_critical_section( &_POSIX_signals_Wait_queue );
-    _ISR_Enable( level );
+    _POSIX_signals_Release( level );
     _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue, executing, interval );
   _Thread_Enable_dispatch();
 
@@ -165,7 +166,14 @@ int sigtimedwait(
    * the signal.
    */
 
-  _POSIX_signals_Clear_signals( api, the_info->si_signo, the_info, false, false );
+  _POSIX_signals_Clear_signals(
+    api,
+    the_info->si_signo,
+    the_info,
+    false,
+    false,
+    true
+  );
 
   /* Set errno only if return code is not EINTR or
    * if EINTR was caused by a signal being caught, which
diff --git a/testsuites/psxtests/psxsignal05/init.c b/testsuites/psxtests/psxsignal05/init.c
index dbd812c..73c25a4 100644
--- a/testsuites/psxtests/psxsignal05/init.c
+++ b/testsuites/psxtests/psxsignal05/init.c
@@ -79,7 +79,8 @@ void *POSIX_Init(
     SIGNAL_ONE,
     &info,
     true,              /* is_global */
-    false              /* check_blocked */
+    false,             /* check_blocked */
+    true               /* do_signals_acquire_release */
   );
   rtems_test_assert( bc );
 




More information about the vc mailing list