From 4054c9164601830c7ead74be612d33c4717d8ea6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 20 Mar 2015 13:41:27 +0100 Subject: score: Add scheduler acquire/release This is currently a global lock for all scheduler instances. It should get replaced with one lock per scheduler instance in the future. Update #2273. --- cpukit/rtems/src/taskmode.c | 6 ++--- cpukit/score/include/rtems/score/schedulerimpl.h | 32 ++++++++++++++++++++++++ cpukit/score/src/scheduler.c | 2 ++ cpukit/score/src/schedulercbsunblock.c | 9 ++++--- cpukit/score/src/threadchangepriority.c | 7 +++--- cpukit/score/src/threadclearstate.c | 23 +++++++++-------- cpukit/score/src/threadready.c | 6 ++--- cpukit/score/src/threadsetstate.c | 8 +++--- cpukit/score/src/threadyield.c | 6 ++--- 9 files changed, 67 insertions(+), 32 deletions(-) (limited to 'cpukit') diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c index 1056c6b11e..de30806186 100644 --- a/cpukit/rtems/src/taskmode.c +++ b/cpukit/rtems/src/taskmode.c @@ -110,12 +110,12 @@ rtems_status_code rtems_task_mode( } if ( preempt_enabled || needs_asr_dispatching ) { - ISR_Level level; + ISR_lock_Context lock_context; _Thread_Disable_dispatch(); - _ISR_Disable( level ); + _Scheduler_Acquire( executing, &lock_context ); _Scheduler_Schedule( executing ); - _ISR_Enable( level ); + _Scheduler_Release( executing, &lock_context ); _Thread_Enable_dispatch(); } diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 43257c4a7a..d11b2c55c8 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -1374,6 +1374,38 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Ask_blocked_node_for_help( } #endif +ISR_LOCK_DECLARE( extern, _Scheduler_Lock ) + +/** + * @brief Acquires the scheduler instance of the thread. + * + * @param[in] the_thread The thread. + * @param[in] lock_context The lock context for _Scheduler_Release(). + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Acquire( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + (void) the_thread; + _ISR_lock_ISR_disable_and_acquire( &_Scheduler_Lock, lock_context ); +} + +/** + * @brief Releases the scheduler instance of the thread. + * + * @param[in] the_thread The thread. + * @param[in] lock_context The lock context used for _Scheduler_Acquire(). + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Release( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + (void) the_thread; + _ISR_lock_Release_and_ISR_enable( &_Scheduler_Lock, lock_context ); +} + /** @} */ #ifdef __cplusplus diff --git a/cpukit/score/src/scheduler.c b/cpukit/score/src/scheduler.c index ef5a0a9c00..e7854e1361 100644 --- a/cpukit/score/src/scheduler.c +++ b/cpukit/score/src/scheduler.c @@ -20,6 +20,8 @@ #include +ISR_LOCK_DEFINE( , _Scheduler_Lock, "Scheduler" ) + void _Scheduler_Handler_initialization(void) { size_t n = _Scheduler_Count; diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c index 56b35de8b9..9170889491 100644 --- a/cpukit/score/src/schedulercbsunblock.c +++ b/cpukit/score/src/schedulercbsunblock.c @@ -53,10 +53,11 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock( if ( deadline*budget_left > budget*deadline_left ) { /* Put late unblocked task to background until the end of period. */ new_priority = the_thread->Start.initial_priority; - if ( the_thread->real_priority != new_priority ) - the_thread->real_priority = new_priority; - if ( the_thread->current_priority != new_priority ) - _Thread_Change_priority(the_thread, new_priority, true); + the_thread->real_priority = new_priority; + if ( the_thread->current_priority != new_priority ) { + the_thread->current_priority = new_priority; + _Scheduler_Change_priority(the_thread, new_priority, true); + } } } diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c index 2baa9d2774..a011a8f5e5 100644 --- a/cpukit/score/src/threadchangepriority.c +++ b/cpukit/score/src/threadchangepriority.c @@ -39,8 +39,7 @@ void _Thread_Change_priority( * we are not REALLY changing priority. */ if ( the_thread->current_priority != new_priority ) { - uint32_t my_generation; - ISR_Level level; + uint32_t my_generation; my_generation = the_thread->Priority.generation + 1; the_thread->current_priority = new_priority; @@ -54,7 +53,7 @@ void _Thread_Change_priority( _Thread_Lock_release( lock, &lock_context ); - _ISR_Disable( level ); + _Scheduler_Acquire( the_thread, &lock_context ); if ( the_thread->Priority.generation == my_generation ) { if ( _States_Is_ready( the_thread->current_state ) ) { @@ -68,7 +67,7 @@ void _Thread_Change_priority( } } - _ISR_Enable( level ); + _Scheduler_Release( the_thread, &lock_context ); } else { _Thread_Lock_release( lock, &lock_context ); } diff --git a/cpukit/score/src/threadclearstate.c b/cpukit/score/src/threadclearstate.c index 19e41df593..c60fb8fc41 100644 --- a/cpukit/score/src/threadclearstate.c +++ b/cpukit/score/src/threadclearstate.c @@ -26,19 +26,20 @@ void _Thread_Clear_state( States_Control state ) { - ISR_Level level; - States_Control current_state; + ISR_lock_Context lock_context; + States_Control current_state; - _ISR_Disable( level ); - current_state = the_thread->current_state; + _Scheduler_Acquire( the_thread, &lock_context ); - if ( current_state & state ) { - current_state = - the_thread->current_state = _States_Clear( state, current_state ); + current_state = the_thread->current_state; + if ( current_state & state ) { + current_state = + the_thread->current_state = _States_Clear( state, current_state ); - if ( _States_Is_ready( current_state ) ) { - _Scheduler_Unblock( the_thread ); - } + if ( _States_Is_ready( current_state ) ) { + _Scheduler_Unblock( the_thread ); + } } - _ISR_Enable( level ); + + _Scheduler_Release( the_thread, &lock_context ); } diff --git a/cpukit/score/src/threadready.c b/cpukit/score/src/threadready.c index b79d8db84d..5375294fe9 100644 --- a/cpukit/score/src/threadready.c +++ b/cpukit/score/src/threadready.c @@ -26,13 +26,13 @@ void _Thread_Ready( Thread_Control *the_thread ) { - ISR_Level level; + ISR_lock_Context lock_context; - _ISR_Disable( level ); + _Scheduler_Acquire( the_thread, &lock_context ); the_thread->current_state = STATES_READY; _Scheduler_Unblock( the_thread ); - _ISR_Enable( level ); + _Scheduler_Release( the_thread, &lock_context ); } diff --git a/cpukit/score/src/threadsetstate.c b/cpukit/score/src/threadsetstate.c index a8cd38efc7..02ee70ed9b 100644 --- a/cpukit/score/src/threadsetstate.c +++ b/cpukit/score/src/threadsetstate.c @@ -30,10 +30,10 @@ void _Thread_Set_state( States_Control state ) { - ISR_Level level; - States_Control current_state; + ISR_lock_Context lock_context; + States_Control current_state; - _ISR_Disable( level ); + _Scheduler_Acquire( the_thread, &lock_context ); current_state = the_thread->current_state; if ( _States_Is_ready( current_state ) ) { @@ -44,5 +44,5 @@ void _Thread_Set_state( the_thread->current_state = _States_Set( state, current_state); } - _ISR_Enable( level ); + _Scheduler_Release( the_thread, &lock_context ); } diff --git a/cpukit/score/src/threadyield.c b/cpukit/score/src/threadyield.c index fc796dabea..7f1c175b4a 100644 --- a/cpukit/score/src/threadyield.c +++ b/cpukit/score/src/threadyield.c @@ -29,13 +29,13 @@ void _Thread_Yield( Thread_Control *executing ) { - ISR_Level level; + ISR_lock_Context lock_context; - _ISR_Disable( level ); + _Scheduler_Acquire( executing, &lock_context ); if ( _States_Is_ready( executing->current_state ) ) { _Scheduler_Yield( executing ); } - _ISR_Enable( level ); + _Scheduler_Release( executing, &lock_context ); } -- cgit v1.2.3