RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
smplockticket.h
Go to the documentation of this file.
1
9/*
10 * Copyright (c) 2013, 2016 embedded brains GmbH
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef _RTEMS_SCORE_SMPLOCKTICKET_H
18#define _RTEMS_SCORE_SMPLOCKTICKET_H
19
20#include <rtems/score/cpuopts.h>
21
22#if defined(RTEMS_SMP)
23
24#include <rtems/score/atomic.h>
26
27#ifdef __cplusplus
28extern "C" {
29#endif /* __cplusplus */
30
40typedef struct {
41 Atomic_Uint next_ticket;
42 Atomic_Uint now_serving;
43} SMP_ticket_lock_Control;
44
48#define SMP_TICKET_LOCK_INITIALIZER \
49 { \
50 ATOMIC_INITIALIZER_UINT( 0U ), \
51 ATOMIC_INITIALIZER_UINT( 0U ) \
52 }
53
61static inline void _SMP_ticket_lock_Initialize(
62 SMP_ticket_lock_Control *lock
63)
64{
65 _Atomic_Init_uint( &lock->next_ticket, 0U );
66 _Atomic_Init_uint( &lock->now_serving, 0U );
67}
68
76static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
77{
78 (void) lock;
79}
80
88static inline void _SMP_ticket_lock_Do_acquire(
89 SMP_ticket_lock_Control *lock
90#if defined(RTEMS_PROFILING)
91 ,
92 SMP_lock_Stats *stats,
93 SMP_lock_Stats_context *stats_context
94#endif
95)
96{
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;
102
103 _SMP_lock_Stats_acquire_begin( &acquire_context );
104#endif
105
106 my_ticket =
107 _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
108
109#if defined(RTEMS_PROFILING)
110 now_serving =
111 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
112 initial_queue_length = my_ticket - now_serving;
113
114 if ( initial_queue_length > 0 ) {
115#endif
116
117 do {
118 now_serving =
119 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
120 } while ( now_serving != my_ticket );
121
122#if defined(RTEMS_PROFILING)
123 }
124
125 _SMP_lock_Stats_acquire_end(
126 &acquire_context,
127 stats,
128 stats_context,
129 initial_queue_length
130 );
131#endif
132}
133
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 )
148#else
149 #define _SMP_ticket_lock_Acquire( lock, stats, stats_context ) \
150 _SMP_ticket_lock_Do_acquire( lock )
151#endif
152
159static inline void _SMP_ticket_lock_Do_release(
160 SMP_ticket_lock_Control *lock
161#if defined(RTEMS_PROFILING)
162 ,
163 const SMP_lock_Stats_context *stats_context
164#endif
165)
166{
167 unsigned int current_ticket =
168 _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
169 unsigned int next_ticket = current_ticket + 1U;
170
171#if defined(RTEMS_PROFILING)
172 _SMP_lock_Stats_release_update( stats_context );
173#endif
174
175 _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
176}
177
184#if defined(RTEMS_PROFILING)
185 #define _SMP_ticket_lock_Release( lock, stats_context ) \
186 _SMP_ticket_lock_Do_release( lock, stats_context )
187#else
188 #define _SMP_ticket_lock_Release( lock, stats_context ) \
189 _SMP_ticket_lock_Do_release( lock )
190#endif
191
194#ifdef __cplusplus
195}
196#endif /* __cplusplus */
197
198#endif /* RTEMS_SMP */
199
200#endif /* _RTEMS_SCORE_SMPLOCKTICKET_H */
Atomic Operations API.
SMP Lock API.