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.
This commit is contained in:
Sebastian Huber
2015-02-23 16:54:54 +01:00
parent b8a5abf3fa
commit 6157743d67
4 changed files with 26 additions and 52 deletions

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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(

View File

@@ -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(