diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-02-20 14:28:17 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-02-20 15:22:29 +0100 |
commit | 508f868237225a75e566d9fd304206363cfe441d (patch) | |
tree | aefc293db63007c9e601950233167cd12da71ac5 /cpukit | |
parent | rtems: Avoid potential recursion in ASR handling (diff) | |
download | rtems-508f868237225a75e566d9fd304206363cfe441d.tar.bz2 |
rtems: Simplify rtems_task_mode()
Do the preemption and ASR processing changes in one rush and acquire the
thread state lock only once.
Diffstat (limited to '')
-rw-r--r-- | cpukit/rtems/src/taskmode.c | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c index 6287d44ac1..377224c98a 100644 --- a/cpukit/rtems/src/taskmode.c +++ b/cpukit/rtems/src/taskmode.c @@ -34,12 +34,9 @@ rtems_status_code rtems_task_mode( rtems_mode *previous_mode_set ) { - ISR_lock_Context lock_context; Thread_Control *executing; RTEMS_API_Control *api; ASR_Information *asr; - bool preempt_enabled; - bool needs_asr_dispatching; rtems_mode old_mode; executing = _Thread_Get_executing(); @@ -86,17 +83,6 @@ rtems_status_code rtems_task_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 ) { _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 ) ); } - /* - * This is specific to the RTEMS API - */ - needs_asr_dispatching = false; - if ( mask & RTEMS_ASR_MASK ) { - bool prev_asr_is_enabled; + if ( ( mask & ( RTEMS_ASR_MASK | RTEMS_PREEMPT_MASK ) ) != 0 ) { + bool need_thread_dispatch; + ISR_lock_Context lock_context; + bool previous_asr_is_enabled; + bool previous_is_preemptible; + + need_thread_dispatch = false; _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 ); if ( - !prev_asr_is_enabled && + !previous_asr_is_enabled && asr->is_enabled && asr->signals_pending != 0 ) { - needs_asr_dispatching = true; + need_thread_dispatch = true; _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 ) { - Per_CPU_Control *cpu_self; + if ( need_thread_dispatch ) { + Per_CPU_Control *cpu_self; - cpu_self = _Thread_Dispatch_disable(); - _Thread_State_acquire( executing, &lock_context ); - _Scheduler_Schedule( executing ); - _Thread_State_release( executing, &lock_context ); - _Thread_Dispatch_direct( cpu_self ); + cpu_self = _Thread_Dispatch_disable_critical( &lock_context ); + _Thread_State_release( executing, &lock_context ); + _Thread_Dispatch_direct( cpu_self ); + } else { + _Thread_State_release( executing, &lock_context ); + } } return RTEMS_SUCCESSFUL; |