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 <rtems/posix/time.h>
|
||||||
#include <stdio.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(
|
bool _POSIX_signals_Unblock_thread(
|
||||||
Thread_Control *the_thread,
|
Thread_Control *the_thread,
|
||||||
int signo,
|
int signo,
|
||||||
@@ -47,8 +58,6 @@ bool _POSIX_signals_Unblock_thread(
|
|||||||
|
|
||||||
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
api = the_thread->API_Extensions[ THREAD_API_POSIX ];
|
||||||
|
|
||||||
_Thread_Add_post_switch_action( the_thread, &api->Signal_action );
|
|
||||||
|
|
||||||
mask = signo_to_mask( signo );
|
mask = signo_to_mask( signo );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -71,14 +80,14 @@ bool _POSIX_signals_Unblock_thread(
|
|||||||
}
|
}
|
||||||
|
|
||||||
_Thread_queue_Extract_with_proxy( the_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().
|
* 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 );
|
(void) _Watchdog_Remove( &the_thread->Timer );
|
||||||
_Thread_Unblock( the_thread );
|
_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,
|
the_thread,
|
||||||
&api->Signal_action
|
&api->Signal_action
|
||||||
);
|
);
|
||||||
_Thread_Signal_notification( the_thread );
|
|
||||||
} else {
|
} else {
|
||||||
_ASR_Post_signals( asr, signal_set, &asr->signals_pending );
|
_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 );
|
_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.
|
* @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
|
Thread_Action *action
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Per_CPU_Control *cpu;
|
Per_CPU_Control *cpu_of_thread;
|
||||||
ISR_Level level;
|
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(
|
_Chain_Append_if_is_off_chain_unprotected(
|
||||||
&thread->Post_switch_actions.Chain,
|
&thread->Post_switch_actions.Chain,
|
||||||
&action->Node
|
&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(
|
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 );
|
_Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
|
||||||
_Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
|
_Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
|
||||||
_Thread_Ready( the_thread );
|
_Thread_Ready( the_thread );
|
||||||
_Thread_Request_dispatch_if_executing( the_thread );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _Thread_Request_life_change(
|
static void _Thread_Request_life_change(
|
||||||
|
|||||||
Reference in New Issue
Block a user