summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-02-23 16:54:54 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-05 11:36:19 +0100
commit6157743d67c79d21996ec2cc9742fd8e4e985be7 (patch)
treebf350ddf23443f898bfd199e139fc91e9d326af8 /cpukit
parentscore: Update _Thread_Heir only if necessary (diff)
downloadrtems-6157743d67c79d21996ec2cc9742fd8e4e985be7.tar.bz2
score: Simplify and fix signal delivery
Deliver the POSIX signals after the thread state was updated to avoid race-conditions on SMP configurations. Update #2273.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/posix/src/psignalunblockthread.c22
-rw-r--r--cpukit/rtems/src/signalsend.c1
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h54
-rw-r--r--cpukit/score/src/threadrestart.c1
4 files changed, 26 insertions, 52 deletions
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index c93dcfc1ce..c56c1502a1 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 cb989c4cbf..c86c399637 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 07c5b2f12a..e5e51ec322 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 cc2d8c349f..10d05f1c15 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(