rtems: Simplify rtems_task_mode()

Do the preemption and ASR processing changes in one rush and acquire the
thread state lock only once.
This commit is contained in:
Sebastian Huber
2021-02-20 14:28:17 +01:00
parent a7e180b95d
commit 508f868237

View File

@@ -34,12 +34,9 @@ rtems_status_code rtems_task_mode(
rtems_mode *previous_mode_set rtems_mode *previous_mode_set
) )
{ {
ISR_lock_Context lock_context;
Thread_Control *executing; Thread_Control *executing;
RTEMS_API_Control *api; RTEMS_API_Control *api;
ASR_Information *asr; ASR_Information *asr;
bool preempt_enabled;
bool needs_asr_dispatching;
rtems_mode old_mode; rtems_mode old_mode;
executing = _Thread_Get_executing(); executing = _Thread_Get_executing();
@@ -86,17 +83,6 @@ rtems_status_code rtems_task_mode(
*previous_mode_set = old_mode; *previous_mode_set = old_mode;
/*
* These are generic thread scheduling characteristics.
*/
preempt_enabled = false;
if ( mask & RTEMS_PREEMPT_MASK ) {
bool is_preempt_enabled = _Modes_Is_preempt( mode_set );
preempt_enabled = !executing->is_preemptible && is_preempt_enabled;
executing->is_preemptible = is_preempt_enabled;
}
if ( ( mask & RTEMS_TIMESLICE_MASK ) != 0 ) { if ( ( mask & RTEMS_TIMESLICE_MASK ) != 0 ) {
_Modes_Apply_timeslice_to_thread( mode_set, executing ); _Modes_Apply_timeslice_to_thread( mode_set, executing );
} }
@@ -105,38 +91,45 @@ rtems_status_code rtems_task_mode(
_ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) ); _ISR_Set_level( _Modes_Get_interrupt_level( mode_set ) );
} }
/* if ( ( mask & ( RTEMS_ASR_MASK | RTEMS_PREEMPT_MASK ) ) != 0 ) {
* This is specific to the RTEMS API bool need_thread_dispatch;
*/ ISR_lock_Context lock_context;
needs_asr_dispatching = false; bool previous_asr_is_enabled;
if ( mask & RTEMS_ASR_MASK ) { bool previous_is_preemptible;
bool prev_asr_is_enabled;
need_thread_dispatch = false;
_Thread_State_acquire( executing, &lock_context ); _Thread_State_acquire( executing, &lock_context );
prev_asr_is_enabled = asr->is_enabled; previous_asr_is_enabled = asr->is_enabled;
asr->is_enabled = !_Modes_Is_asr_disabled( mode_set ); asr->is_enabled = !_Modes_Is_asr_disabled( mode_set );
if ( if (
!prev_asr_is_enabled && !previous_asr_is_enabled &&
asr->is_enabled && asr->is_enabled &&
asr->signals_pending != 0 asr->signals_pending != 0
) { ) {
needs_asr_dispatching = true; need_thread_dispatch = true;
_Thread_Append_post_switch_action( executing, &api->Signal_action ); _Thread_Append_post_switch_action( executing, &api->Signal_action );
} }
_Thread_State_release( executing, &lock_context ); previous_is_preemptible = executing->is_preemptible;
executing->is_preemptible = _Modes_Is_preempt( mode_set );
if ( executing->is_preemptible && !previous_is_preemptible ) {
need_thread_dispatch = true;
_Scheduler_Schedule( executing );
} }
if ( preempt_enabled || needs_asr_dispatching ) { if ( need_thread_dispatch ) {
Per_CPU_Control *cpu_self; Per_CPU_Control *cpu_self;
cpu_self = _Thread_Dispatch_disable(); cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
_Thread_State_acquire( executing, &lock_context );
_Scheduler_Schedule( executing );
_Thread_State_release( executing, &lock_context ); _Thread_State_release( executing, &lock_context );
_Thread_Dispatch_direct( cpu_self ); _Thread_Dispatch_direct( cpu_self );
} else {
_Thread_State_release( executing, &lock_context );
}
} }
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;