17#ifndef _RTEMS_SCORE_SMPLOCKTICKET_H
18#define _RTEMS_SCORE_SMPLOCKTICKET_H
20#include <rtems/score/cpuopts.h>
41 Atomic_Uint next_ticket;
42 Atomic_Uint now_serving;
43} SMP_ticket_lock_Control;
48#define SMP_TICKET_LOCK_INITIALIZER \
50 ATOMIC_INITIALIZER_UINT( 0U ), \
51 ATOMIC_INITIALIZER_UINT( 0U ) \
61static inline void _SMP_ticket_lock_Initialize(
62 SMP_ticket_lock_Control *lock
65 _Atomic_Init_uint( &lock->next_ticket, 0U );
66 _Atomic_Init_uint( &lock->now_serving, 0U );
76static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
88static inline void _SMP_ticket_lock_Do_acquire(
89 SMP_ticket_lock_Control *lock
90#
if defined(RTEMS_PROFILING)
92 SMP_lock_Stats *stats,
93 SMP_lock_Stats_context *stats_context
97 unsigned int my_ticket;
98 unsigned int now_serving;
99#if defined(RTEMS_PROFILING)
100 unsigned int initial_queue_length;
101 SMP_lock_Stats_acquire_context acquire_context;
103 _SMP_lock_Stats_acquire_begin( &acquire_context );
107 _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
109#if defined(RTEMS_PROFILING)
111 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
112 initial_queue_length = my_ticket - now_serving;
114 if ( initial_queue_length > 0 ) {
119 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
120 }
while ( now_serving != my_ticket );
122#if defined(RTEMS_PROFILING)
125 _SMP_lock_Stats_acquire_end(
145#if defined(RTEMS_PROFILING)
146 #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
147 _SMP_ticket_lock_Do_acquire( lock, stats, stats_context )
149 #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
150 _SMP_ticket_lock_Do_acquire( lock )
159static inline void _SMP_ticket_lock_Do_release(
160 SMP_ticket_lock_Control *lock
161#
if defined(RTEMS_PROFILING)
163 const SMP_lock_Stats_context *stats_context
167 unsigned int current_ticket =
168 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
169 unsigned int next_ticket = current_ticket + 1U;
171#if defined(RTEMS_PROFILING)
172 _SMP_lock_Stats_release_update( stats_context );
175 _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
184#if defined(RTEMS_PROFILING)
185 #define _SMP_ticket_lock_Release( lock, stats_context ) \
186 _SMP_ticket_lock_Do_release( lock, stats_context )
188 #define _SMP_ticket_lock_Release( lock, stats_context ) \
189 _SMP_ticket_lock_Do_release( lock )