forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
#include <rtems/score/basedefs.h>
|
||||
#include <rtems/score/chain.h>
|
||||
#include <rtems/score/priority.h>
|
||||
#include <rtems/score/smplockseq.h>
|
||||
#include <rtems/score/isrlock.h>
|
||||
|
||||
/**
|
||||
* @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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
#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;
|
||||
|
||||
do {
|
||||
seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock );
|
||||
#endif
|
||||
|
||||
priority = node->Priority.value;
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
#endif
|
||||
|
||||
#include <rtems/score/scheduler.h>
|
||||
#include <rtems/score/schedulernodeimpl.h>
|
||||
|
||||
void _Scheduler_default_Node_destroy(
|
||||
const Scheduler_Control *scheduler,
|
||||
Scheduler_Node *node
|
||||
)
|
||||
{
|
||||
(void) scheduler;
|
||||
(void) node;
|
||||
_Scheduler_Node_do_destroy( scheduler, node );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user