forked from Imagelibrary/rtems
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:
@@ -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 ( preempt_enabled || needs_asr_dispatching ) {
|
if ( executing->is_preemptible && !previous_is_preemptible ) {
|
||||||
Per_CPU_Control *cpu_self;
|
need_thread_dispatch = true;
|
||||||
|
_Scheduler_Schedule( executing );
|
||||||
|
}
|
||||||
|
|
||||||
cpu_self = _Thread_Dispatch_disable();
|
if ( need_thread_dispatch ) {
|
||||||
_Thread_State_acquire( executing, &lock_context );
|
Per_CPU_Control *cpu_self;
|
||||||
_Scheduler_Schedule( executing );
|
|
||||||
_Thread_State_release( executing, &lock_context );
|
cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
|
||||||
_Thread_Dispatch_direct( cpu_self );
|
_Thread_State_release( executing, &lock_context );
|
||||||
|
_Thread_Dispatch_direct( cpu_self );
|
||||||
|
} else {
|
||||||
|
_Thread_State_release( executing, &lock_context );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
|
|||||||
Reference in New Issue
Block a user