DPDK  19.08.2
rte_ticketlock.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Arm Limited
3  */
4 
5 #ifndef _RTE_TICKETLOCK_H_
6 #define _RTE_TICKETLOCK_H_
7 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #include <rte_common.h>
26 #include <rte_lcore.h>
27 #include <rte_pause.h>
28 
32 typedef union {
33  uint32_t tickets;
34  struct {
35  uint16_t current;
36  uint16_t next;
37  } s;
39 
43 #define RTE_TICKETLOCK_INITIALIZER { 0 }
44 
51 __rte_experimental
52 static inline void
54 {
55  __atomic_store_n(&tl->tickets, 0, __ATOMIC_RELAXED);
56 }
57 
64 __rte_experimental
65 static inline void
67 {
68  uint16_t me = __atomic_fetch_add(&tl->s.next, 1, __ATOMIC_RELAXED);
69  while (__atomic_load_n(&tl->s.current, __ATOMIC_ACQUIRE) != me)
70  rte_pause();
71 }
72 
79 __rte_experimental
80 static inline void
82 {
83  uint16_t i = __atomic_load_n(&tl->s.current, __ATOMIC_RELAXED);
84  __atomic_store_n(&tl->s.current, i + 1, __ATOMIC_RELEASE);
85 }
86 
95 __rte_experimental
96 static inline int
98 {
99  rte_ticketlock_t old, new;
100  old.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_RELAXED);
101  new.tickets = old.tickets;
102  new.s.next++;
103  if (old.s.next == old.s.current) {
104  if (__atomic_compare_exchange_n(&tl->tickets, &old.tickets,
105  new.tickets, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
106  return 1;
107  }
108 
109  return 0;
110 }
111 
120 __rte_experimental
121 static inline int
123 {
124  rte_ticketlock_t tic;
125  tic.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_ACQUIRE);
126  return (tic.s.current != tic.s.next);
127 }
128 
132 #define TICKET_LOCK_INVALID_ID -1
133 
134 typedef struct {
135  rte_ticketlock_t tl;
136  int user;
137  unsigned int count;
138 } rte_ticketlock_recursive_t;
139 
143 #define RTE_TICKETLOCK_RECURSIVE_INITIALIZER {RTE_TICKETLOCK_INITIALIZER, \
144  TICKET_LOCK_INVALID_ID, 0}
145 
152 __rte_experimental
153 static inline void
154 rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)
155 {
156  rte_ticketlock_init(&tlr->tl);
157  __atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID, __ATOMIC_RELAXED);
158  tlr->count = 0;
159 }
160 
167 __rte_experimental
168 static inline void
169 rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)
170 {
171  int id = rte_gettid();
172 
173  if (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {
174  rte_ticketlock_lock(&tlr->tl);
175  __atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);
176  }
177  tlr->count++;
178 }
179 
186 __rte_experimental
187 static inline void
188 rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)
189 {
190  if (--(tlr->count) == 0) {
191  __atomic_store_n(&tlr->user, TICKET_LOCK_INVALID_ID,
192  __ATOMIC_RELAXED);
193  rte_ticketlock_unlock(&tlr->tl);
194  }
195 }
196 
205 __rte_experimental
206 static inline int
207 rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)
208 {
209  int id = rte_gettid();
210 
211  if (__atomic_load_n(&tlr->user, __ATOMIC_RELAXED) != id) {
212  if (rte_ticketlock_trylock(&tlr->tl) == 0)
213  return 0;
214  __atomic_store_n(&tlr->user, id, __ATOMIC_RELAXED);
215  }
216  tlr->count++;
217  return 1;
218 }
219 
220 #ifdef __cplusplus
221 }
222 #endif
223 
224 #endif /* _RTE_TICKETLOCK_H_ */
#define TICKET_LOCK_INVALID_ID
static __rte_experimental void rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)
static __rte_experimental void rte_ticketlock_lock(rte_ticketlock_t *tl)
static __rte_experimental void rte_ticketlock_unlock(rte_ticketlock_t *tl)
static __rte_experimental void rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)
static __rte_experimental void rte_ticketlock_init(rte_ticketlock_t *tl)
static __rte_experimental int rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)
static void rte_pause(void)
static __rte_experimental int rte_ticketlock_trylock(rte_ticketlock_t *tl)
static __rte_experimental int rte_ticketlock_is_locked(rte_ticketlock_t *tl)
static __rte_experimental void rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)
static int rte_gettid(void)
Definition: rte_eal.h:500