DPDK 21.11.9
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
22extern "C" {
23#endif
24
25#include <rte_common.h>
26#include <rte_lcore.h>
27#include <rte_pause.h>
28
32typedef 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
51static inline void
53{
54 __atomic_store_n(&tl->tickets, 0, __ATOMIC_RELAXED);
55}
56
63static inline void
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
76static inline void
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
91static inline int
93{
94 rte_ticketlock_t oldl, newl;
95 oldl.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_RELAXED);
96 newl.tickets = oldl.tickets;
97 newl.s.next++;
98 if (oldl.s.next == oldl.s.current) {
99 if (__atomic_compare_exchange_n(&tl->tickets, &oldl.tickets,
100 newl.tickets, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
101 return 1;
102 }
103
104 return 0;
105}
106
115static inline int
117{
119 tic.tickets = __atomic_load_n(&tl->tickets, __ATOMIC_ACQUIRE);
120 return (tic.s.current != tic.s.next);
121}
122
126#define TICKET_LOCK_INVALID_ID -1
127
128typedef struct {
130 int user;
131 unsigned int count;
132} rte_ticketlock_recursive_t;
133
137#define RTE_TICKETLOCK_RECURSIVE_INITIALIZER {RTE_TICKETLOCK_INITIALIZER, \
138 TICKET_LOCK_INVALID_ID, 0}
139
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
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
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
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 /* _RTE_TICKETLOCK_H_ */
static int rte_gettid(void)
Definition: rte_eal.h:445
static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, int memorder)
Definition: rte_pause.h:86
#define TICKET_LOCK_INVALID_ID
static void rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)
static void rte_ticketlock_init(rte_ticketlock_t *tl)
static void rte_ticketlock_unlock(rte_ticketlock_t *tl)
static void rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)
static void rte_ticketlock_lock(rte_ticketlock_t *tl)
static void rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)
static int rte_ticketlock_is_locked(rte_ticketlock_t *tl)
static int rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)
static int rte_ticketlock_trylock(rte_ticketlock_t *tl)