forked from Imagelibrary/rtems
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:
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user