1
2
3
4
5#ifndef _RTE_TICKETLOCK_H_
6#define _RTE_TICKETLOCK_H_
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25#include <rte_common.h>
26#include <rte_lcore.h>
27#include <rte_pause.h>
28
29
30
31
32typedef union {
33 uint32_t tickets;
34 struct {
35 uint16_t current;
36 uint16_t next;
37 } s;
38} rte_ticketlock_t;
39
40
41
42
43#define RTE_TICKETLOCK_INITIALIZER { 0 }
44
45
46
47
48
49
50
51static inline void
52rte_ticketlock_init(rte_ticketlock_t *tl)
53{
54 __atomic_store_n(&tl->tickets, 0, __ATOMIC_RELAXED);
55}
56
57
58
59
60
61
62
63static inline void
64rte_ticketlock_lock(rte_ticketlock_t *tl)
65{
66 uint16_t me = __atomic_fetch_add(&tl->s.next, 1, __ATOMIC_RELAXED);
67 rte_wait_until_equal_16(&tl->s.current, me, __ATOMIC_ACQUIRE);
68}
69
70
71
72
73
74
75
76static inline void
77rte_ticketlock_unlock(rte_ticketlock_t *tl)
78{
79 uint16_t i = __atomic_load_n(&tl->s.current, __ATOMIC_RELAXED);
80 __atomic_store_n(&tl->s.current, i + 1, __ATOMIC_RELEASE);
81}
82
83
84
85
86
87
88
89
90
91static inline int
92rte_ticketlock_trylock(rte_ticketlock_t *tl)
93{
94 rte_ticketlock_t old, new;
95 old.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_RELAXED);
96 new.tickets = old.tickets;
97 new.s.next++;
98 if (old.s.next == old.s.current) {
99 if (__atomic_compare_exchange_n(&tl->tickets, &old.tickets,
100 new.tickets, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
101 return 1;
102 }
103
104 return 0;
105}
106
107
108
109
110
111
112
113
114
115static inline int
116rte_ticketlock_is_locked(rte_ticketlock_t *tl)
117{
118 rte_ticketlock_t tic;
119 tic.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_ACQUIRE);
120 return (tic.s.current != tic.s.next);
121}
122
123
124
125
126#define TICKET_LOCK_INVALID_ID -1
127
128typedef struct {
129 rte_ticketlock_t tl;
130 int user;
131 unsigned int count;
132} rte_ticketlock_recursive_t;
133
134
135
136
137#define RTE_TICKETLOCK_RECURSIVE_INITIALIZER {RTE_TICKETLOCK_INITIALIZER, \
138 TICKET_LOCK_INVALID_ID, 0}
139
140
141
142
143
144
145
146static inline void
147rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)
148{
149 rte_ticketlock_init(&tlr->tl);
150 __atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID, __ATOMIC_RELAXED);
151 tlr->count = 0;
152}
153
154
155
156
157
158
159
160static inline void
161rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)
162{
163 int id = rte_gettid();
164
165 if (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {
166 rte_ticketlock_lock(&tlr->tl);
167 __atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);
168 }
169 tlr->count++;
170}
171
172
173
174
175
176
177
178static inline void
179rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)
180{
181 if (--(tlr->count) == 0) {
182 __atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID,
183 __ATOMIC_RELAXED);
184 rte_ticketlock_unlock(&tlr->tl);
185 }
186}
187
188
189
190
191
192
193
194
195
196static inline int
197rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)
198{
199 int id = rte_gettid();
200
201 if (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {
202 if (rte_ticketlock_trylock(&tlr->tl) == 0)
203 return 0;
204 __atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);
205 }
206 tlr->count++;
207 return 1;
208}
209
210#ifdef __cplusplus
211}
212#endif
213
214#endif
215