summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems/src/taskmode.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-02-20 14:28:17 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-02-20 15:22:29 +0100
commit508f868237225a75e566d9fd304206363cfe441d (patch)
treeaefc293db63007c9e601950233167cd12da71ac5 /cpukit/rtems/src/taskmode.c
parentrtems: Avoid potential recursion in ASR handling (diff)
downloadrtems-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.c57
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;