[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