From a0ec14ca223390f7961c6dfe950edd4db4c777c3 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 10 Aug 2021 16:28:24 +0200 Subject: score: Replace the single use of a sequence lock In SMP configurations, on 64-bit architectures use plain atomic operations to set/get the priority value of a scheduler node. On 32-bit architectures use an ISR lock. Using a sequence lock has no real benefit since it uses atomic read-modify-write operations for both the read and the write lock. Simply use a ticket lock instead so that only one SMP synchronization primitive is used for everything. --- cpukit/include/rtems/score/schedulernode.h | 14 +++-- cpukit/include/rtems/score/schedulernodeimpl.h | 77 ++++++++++++++++++-------- cpukit/score/src/schedulerdefaultnodedestroy.c | 4 +- 3 files changed, 65 insertions(+), 30 deletions(-) (limited to 'cpukit') diff --git a/cpukit/include/rtems/score/schedulernode.h b/cpukit/include/rtems/score/schedulernode.h index 1dba200dca..e344479718 100644 --- a/cpukit/include/rtems/score/schedulernode.h +++ b/cpukit/include/rtems/score/schedulernode.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include /** * @addtogroup RTEMSScoreScheduler @@ -197,14 +197,20 @@ struct Scheduler_Node { * least-significant bit which indicates if the thread should be appended * (bit set) or prepended (bit cleared) to its priority group, see * SCHEDULER_PRIORITY_APPEND(). + * + * @see _Scheduler_Node_get_priority() and _Scheduler_Node_set_priority(). */ +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8 + Atomic_Ulong value; +#else Priority_Control value; +#endif -#if defined(RTEMS_SMP) +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER != 8 /** - * @brief Sequence lock to synchronize priority value updates. + * @brief The lock protects the priority value. */ - SMP_sequence_lock_Control Lock; + ISR_lock_Control Lock; #endif } Priority; }; diff --git a/cpukit/include/rtems/score/schedulernodeimpl.h b/cpukit/include/rtems/score/schedulernodeimpl.h index 9b5c632d86..e222de953b 100644 --- a/cpukit/include/rtems/score/schedulernodeimpl.h +++ b/cpukit/include/rtems/score/schedulernodeimpl.h @@ -77,12 +77,15 @@ extern "C" { ( ( ( priority ) & ( (Priority_Control) PRIORITY_GROUP_LAST ) ) != 0 ) /** - * @brief Initializes a node. + * @brief Initializes the node. * - * @param scheduler The scheduler for the initialization of @a node. - * @param[out] node The node to initialize. - * @param the_thread The thread for the initialization of @a node. - * @param priority The priority value for @a node. + * @param scheduler is the scheduler of the node. + * + * @param[out] node is the node to initialize. + * + * @param[in, out] the_thread is the thread of the node. + * + * @param priority is the initial priority of the node. */ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( const struct _Scheduler_Control *scheduler, @@ -100,13 +103,36 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( node->Wait.Priority.scheduler = scheduler; node->user = the_thread; node->idle = NULL; - _SMP_sequence_lock_Initialize( &node->Priority.Lock ); +#if CPU_SIZEOF_POINTER != 8 + _ISR_lock_Initialize( &node->Priority.Lock, "Scheduler Node Priority" ); +#endif #else (void) scheduler; (void) the_thread; #endif } +/** + * @brief Destroys the node. + * + * @param scheduler is the scheduler of the node. + * + * @param[in, out] node is the node to destroy. + */ +RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_destroy( + const struct _Scheduler_Control *scheduler, + Scheduler_Node *node +) +{ + (void) scheduler; + +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER != 8 + _ISR_lock_Destroy( &node->Priority.Lock ); +#else + (void) node; +#endif +} + /** * @brief Gets the scheduler of the node. * @@ -148,17 +174,18 @@ RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority( { Priority_Control priority; -#if defined(RTEMS_SMP) - unsigned int seq; - - do { - seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock ); -#endif - - priority = node->Priority.value; +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8 + priority = _Atomic_Fetch_add_ulong( + &node->Priority.value, + 0, + ATOMIC_ORDER_RELAXED + ); +#else + ISR_lock_Context lock_context; -#if defined(RTEMS_SMP) - } while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) ); + _ISR_lock_Acquire( &node->Priority.Lock, &lock_context ); + priority = node->Priority.value; + _ISR_lock_Release( &node->Priority.Lock, &lock_context ); #endif return priority; @@ -180,16 +207,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority( Priority_Group_order group_order ) { -#if defined(RTEMS_SMP) - unsigned int seq; - - seq = _SMP_sequence_lock_Write_begin( &node->Priority.Lock ); -#endif +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8 + _Atomic_Store_ulong( + &node->Priority.value, + new_priority | (Priority_Control) group_order, + ATOMIC_ORDER_RELAXED + ); +#else + ISR_lock_Context lock_context; + _ISR_lock_Acquire( &node->Priority.Lock, &lock_context ); node->Priority.value = new_priority | ( (Priority_Control) group_order ); - -#if defined(RTEMS_SMP) - _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq ); + _ISR_lock_Release( &node->Priority.Lock, &lock_context ); #endif } diff --git a/cpukit/score/src/schedulerdefaultnodedestroy.c b/cpukit/score/src/schedulerdefaultnodedestroy.c index 796896d854..33cdfd4c69 100644 --- a/cpukit/score/src/schedulerdefaultnodedestroy.c +++ b/cpukit/score/src/schedulerdefaultnodedestroy.c @@ -21,12 +21,12 @@ #endif #include +#include void _Scheduler_default_Node_destroy( const Scheduler_Control *scheduler, Scheduler_Node *node ) { - (void) scheduler; - (void) node; + _Scheduler_Node_do_destroy( scheduler, node ); } -- cgit v1.2.3