[PATCH 2/8] score: Simplify and fix signal delivery

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Mar 4 15:07:02 UTC 2015


Deliver the POSIX signals after the thread state was updated to avoid
race-conditions on SMP configurations.

Update #2273.
---
 cpukit/posix/src/psignalunblockthread.c       | 22 +++++++----
 cpukit/rtems/src/signalsend.c                 |  1 -
 cpukit/score/include/rtems/score/threadimpl.h | 54 ++++++---------------------
 cpukit/score/src/threadrestart.c              |  1 -
 4 files changed, 26 insertions(+), 52 deletions(-)

diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index c93dcfc..c56c150 100644
--- a/cpukit/posix/src/psignalunblockthread.c
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -35,6 +35,17 @@
 #include <rtems/posix/time.h>
 #include <stdio.h>
 
+static bool _POSIX_signals_Unblock_thread_done(
+  Thread_Control    *the_thread,
+  POSIX_API_Control *api,
+  bool               status
+)
+{
+  _Thread_Add_post_switch_action( the_thread, &api->Signal_action );
+
+  return status;
+}
+
 bool _POSIX_signals_Unblock_thread(
   Thread_Control  *the_thread,
   int              signo,
@@ -47,8 +58,6 @@ bool _POSIX_signals_Unblock_thread(
 
   api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
-  _Thread_Add_post_switch_action( the_thread, &api->Signal_action );
-
   mask = signo_to_mask( signo );
 
   /*
@@ -71,14 +80,14 @@ bool _POSIX_signals_Unblock_thread(
       }
 
       _Thread_queue_Extract_with_proxy( the_thread );
-      return true;
+      return _POSIX_signals_Unblock_thread_done( the_thread, api, true );
     }
 
     /*
      *  This should only be reached via pthread_kill().
      */
 
-    return false;
+    return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
   }
 
   /*
@@ -111,10 +120,7 @@ bool _POSIX_signals_Unblock_thread(
           (void) _Watchdog_Remove( &the_thread->Timer );
           _Thread_Unblock( the_thread );
        }
-
-    } else if ( the_thread->current_state == STATES_READY ) {
-      _Thread_Signal_notification( the_thread );
     }
   }
-  return false;
+  return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
 }
diff --git a/cpukit/rtems/src/signalsend.c b/cpukit/rtems/src/signalsend.c
index cb989c4..c86c399 100644
--- a/cpukit/rtems/src/signalsend.c
+++ b/cpukit/rtems/src/signalsend.c
@@ -51,7 +51,6 @@ rtems_status_code rtems_signal_send(
             the_thread,
             &api->Signal_action
           );
-          _Thread_Signal_notification( the_thread );
         } else {
           _ASR_Post_signals( asr, signal_set, &asr->signals_pending );
         }
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 07c5b2f..e5e51ec 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -695,45 +695,6 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
     _Objects_Allocate_unprotected( &_Thread_Internal_information );
 }
 
-RTEMS_INLINE_ROUTINE void _Thread_Request_dispatch_if_executing(
-  Thread_Control *thread
-)
-{
-#if defined(RTEMS_SMP)
-  if ( _Thread_Is_executing_on_a_processor( thread ) ) {
-    const Per_CPU_Control *cpu_of_executing = _Per_CPU_Get();
-    Per_CPU_Control *cpu_of_thread = _Thread_Get_CPU( thread );
-
-    cpu_of_thread->dispatch_necessary = true;
-
-    if ( cpu_of_executing != cpu_of_thread ) {
-      _Per_CPU_Send_interrupt( cpu_of_thread );
-    }
-  }
-#else
-  (void) thread;
-#endif
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Signal_notification( Thread_Control *thread )
-{
-  if ( _ISR_Is_in_progress() && _Thread_Is_executing( thread ) ) {
-    _Thread_Dispatch_necessary = true;
-  } else {
-#if defined(RTEMS_SMP)
-    if ( _Thread_Is_executing_on_a_processor( thread ) ) {
-      const Per_CPU_Control *cpu_of_executing = _Per_CPU_Get();
-      Per_CPU_Control *cpu_of_thread = _Thread_Get_CPU( thread );
-
-      if ( cpu_of_executing != cpu_of_thread ) {
-        cpu_of_thread->dispatch_necessary = true;
-        _Per_CPU_Send_interrupt( cpu_of_thread );
-      }
-    }
-#endif
-  }
-}
-
 /**
  * @brief Gets the heir of the processor and makes it executing.
  *
@@ -870,15 +831,24 @@ RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
   Thread_Action  *action
 )
 {
-  Per_CPU_Control *cpu;
+  Per_CPU_Control *cpu_of_thread;
   ISR_Level        level;
 
-  cpu = _Thread_Action_ISR_disable_and_acquire( thread, &level );
+  cpu_of_thread = _Thread_Action_ISR_disable_and_acquire( thread, &level );
+  cpu_of_thread->dispatch_necessary = true;
+
+#if defined(RTEMS_SMP)
+  if ( _Per_CPU_Get() != cpu_of_thread ) {
+    _Per_CPU_Send_interrupt( cpu_of_thread );
+  }
+#endif
+
   _Chain_Append_if_is_off_chain_unprotected(
     &thread->Post_switch_actions.Chain,
     &action->Node
   );
-  _Thread_Action_release_and_ISR_enable( cpu, level );
+
+  _Thread_Action_release_and_ISR_enable( cpu_of_thread, level );
 }
 
 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_restarting(
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index cc2d8c3..10d05f1 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -235,7 +235,6 @@ static void _Thread_Start_life_change(
   _Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
   _Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
   _Thread_Ready( the_thread );
-  _Thread_Request_dispatch_if_executing( the_thread );
 }
 
 static void _Thread_Request_life_change(
-- 
1.8.4.5



More information about the devel mailing list