From bd12dda405e1bab16c522f7ef0dd2b455230d269 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 11 May 2016 11:54:49 +0200 Subject: score: Use thread state lock for current state In addition protect scheduler of thread by thread state lock. Enables use of scheduler per-instance locks. Update #2555. --- cpukit/score/include/rtems/score/schedulerimpl.h | 134 +++++++++++++++-------- cpukit/score/include/rtems/score/thread.h | 7 +- 2 files changed, 95 insertions(+), 46 deletions(-) (limited to 'cpukit/score/include/rtems') diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 5cf3503045..c888237376 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -10,7 +10,7 @@ /* * Copyright (C) 2010 Gedare Bloom. * Copyright (C) 2011 On-Line Applications Research Corporation (OAR). - * Copyright (c) 2014-2015 embedded brains GmbH + * Copyright (c) 2014, 2016 embedded brains GmbH * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -118,6 +118,42 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user( } #endif +ISR_LOCK_DECLARE( extern, _Scheduler_Lock ) + +/** + * @brief Acquires the scheduler instance inside a critical section (interrupts + * disabled). + * + * @param[in] scheduler The scheduler instance. + * @param[in] lock_context The lock context to use for + * _Scheduler_Release_critical(). + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Acquire_critical( + const Scheduler_Control *scheduler, + ISR_lock_Context *lock_context +) +{ + (void) scheduler; + _ISR_lock_Acquire( &_Scheduler_Lock, lock_context ); +} + +/** + * @brief Releases the scheduler instance inside a critical section (interrupts + * disabled). + * + * @param[in] scheduler The scheduler instance. + * @param[in] lock_context The lock context used for + * _Scheduler_Acquire_critical(). + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical( + const Scheduler_Control *scheduler, + ISR_lock_Context *lock_context +) +{ + (void) scheduler; + _ISR_lock_Release( &_Scheduler_Lock, lock_context ); +} + /** * The preferred method to add a new scheduler is to define the jump table * entries and add a case to the _Scheduler_Initialize routine. @@ -143,9 +179,15 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user( */ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; + + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.schedule )( scheduler, the_thread ); + + _Scheduler_Release_critical( scheduler, &lock_context ); } #if defined(RTEMS_SMP) @@ -252,10 +294,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help_if_necessary( */ RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; #if defined(RTEMS_SMP) - Thread_Control *needs_help; + Thread_Control *needs_help; +#endif + + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); +#if defined(RTEMS_SMP) needs_help = #endif ( *scheduler->Operations.yield )( scheduler, the_thread ); @@ -263,6 +311,8 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread ) #if defined(RTEMS_SMP) _Scheduler_Ask_for_help_if_necessary( needs_help ); #endif + + _Scheduler_Release_critical( scheduler, &lock_context ); } /** @@ -277,9 +327,15 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread ) */ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; + + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.block )( scheduler, the_thread ); + + _Scheduler_Release_critical( scheduler, &lock_context ); } /** @@ -294,10 +350,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread ) */ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; #if defined(RTEMS_SMP) - Thread_Control *needs_help; + Thread_Control *needs_help; +#endif + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); + +#if defined(RTEMS_SMP) needs_help = #endif ( *scheduler->Operations.unblock )( scheduler, the_thread ); @@ -305,6 +367,8 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread ) #if defined(RTEMS_SMP) _Scheduler_Ask_for_help_if_necessary( needs_help ); #endif + + _Scheduler_Release_critical( scheduler, &lock_context ); } /** @@ -329,14 +393,20 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority( bool prepend_it ) { - const Scheduler_Control *scheduler = _Scheduler_Get_own( the_thread ); + const Scheduler_Control *own_scheduler; + ISR_lock_Context lock_context; #if defined(RTEMS_SMP) - Thread_Control *needs_help; + Thread_Control *needs_help; +#endif + own_scheduler = _Scheduler_Get_own( the_thread ); + _Scheduler_Acquire_critical( own_scheduler, &lock_context ); + +#if defined(RTEMS_SMP) needs_help = #endif - ( *scheduler->Operations.change_priority )( - scheduler, + ( *own_scheduler->Operations.change_priority )( + own_scheduler, the_thread, new_priority, prepend_it @@ -345,6 +415,8 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority( #if defined(RTEMS_SMP) _Scheduler_Ask_for_help_if_necessary( needs_help ); #endif + + _Scheduler_Release_critical( own_scheduler, &lock_context ); } /** @@ -394,13 +466,19 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Priority_Control new_priority ) { - const Scheduler_Control *scheduler = _Scheduler_Get( the_thread ); + const Scheduler_Control *scheduler; + ISR_lock_Context lock_context; + + scheduler = _Scheduler_Get( the_thread ); + _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.update_priority )( scheduler, the_thread, new_priority ); + + _Scheduler_Release_critical( scheduler, &lock_context ); } /** @@ -1341,8 +1419,6 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Ask_blocked_node_for_help( } #endif -ISR_LOCK_DECLARE( extern, _Scheduler_Lock ) - RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir( Thread_Control *new_heir, bool force_dispatch @@ -1367,36 +1443,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Update_heir( } } -/** - * @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/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index d2a6d4b5bd..15b068d92b 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -718,8 +718,11 @@ struct _Thread_Control { * The lock of this thread queue is used for various purposes. It protects * the following fields * - * - RTEMS_API_Control::Signal, and - * - Thread_Control::Post_switch_actions. + * - RTEMS_API_Control::Signal, + * - Thread_Control::current_state, + * - Thread_Control::Post_switch_actions, + * - Thread_Control::Scheduler::control, and + * - Thread_Control::Scheduler::own_control. * * @see _Thread_State_acquire(). */ -- cgit v1.2.3