DPDK
25.11.0
Toggle main menu visibility
Loading...
Searching...
No Matches
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
19
20
#include <
rte_common.h
>
21
#include <
rte_lcore.h
>
22
#include <
rte_pause.h
>
23
#include <rte_stdatomic.h>
24
25
#ifdef __cplusplus
26
extern
"C"
{
27
#endif
28
32
typedef
union
{
33
RTE_ATOMIC(uint32_t) tickets;
34
struct
{
35
RTE_ATOMIC(uint16_t) current;
36
RTE_ATOMIC(uint16_t) next;
37
} s;
38
}
rte_ticketlock_t
;
39
43
#define RTE_TICKETLOCK_INITIALIZER { 0 }
44
51
static
inline
void
52
rte_ticketlock_init
(
rte_ticketlock_t
*tl)
53
{
54
rte_atomic_store_explicit(&tl->tickets, 0, rte_memory_order_relaxed);
55
}
56
63
static
inline
void
64
rte_ticketlock_lock
(
rte_ticketlock_t
*tl)
65
{
66
uint16_t me = rte_atomic_fetch_add_explicit(&tl->s.next, 1, rte_memory_order_relaxed);
67
rte_wait_until_equal_16
((uint16_t *)(uintptr_t)&tl->s.current, me,
68
rte_memory_order_acquire);
69
}
70
77
static
inline
void
78
rte_ticketlock_unlock
(
rte_ticketlock_t
*tl)
79
{
80
uint16_t i = rte_atomic_load_explicit(&tl->s.current, rte_memory_order_relaxed);
81
rte_atomic_store_explicit(&tl->s.current, i + 1, rte_memory_order_release);
82
}
83
92
static
inline
int
93
rte_ticketlock_trylock
(
rte_ticketlock_t
*tl)
94
{
95
rte_ticketlock_t
oldl, newl;
96
oldl.tickets = rte_atomic_load_explicit(&tl->tickets, rte_memory_order_relaxed);
97
newl.tickets = oldl.tickets;
98
newl.s.next++;
99
if
(oldl.s.next == oldl.s.current) {
100
if
(rte_atomic_compare_exchange_strong_explicit(&tl->tickets,
101
(uint32_t *)(uintptr_t)&oldl.tickets, newl.tickets,
102
rte_memory_order_acquire, rte_memory_order_relaxed))
103
return
1;
104
}
105
106
return
0;
107
}
108
117
static
inline
int
118
rte_ticketlock_is_locked
(
rte_ticketlock_t
*tl)
119
{
120
rte_ticketlock_t
tic;
121
tic.tickets = rte_atomic_load_explicit(&tl->tickets, rte_memory_order_acquire);
122
return
(tic.s.current != tic.s.next);
123
}
124
128
#define TICKET_LOCK_INVALID_ID -1
129
130
typedef
struct
{
131
rte_ticketlock_t
tl;
132
RTE_ATOMIC(
int
) user;
133
unsigned
int
count;
134
} rte_ticketlock_recursive_t;
135
139
#define RTE_TICKETLOCK_RECURSIVE_INITIALIZER {RTE_TICKETLOCK_INITIALIZER, \
140
TICKET_LOCK_INVALID_ID, 0}
141
148
static
inline
void
149
rte_ticketlock_recursive_init
(rte_ticketlock_recursive_t *tlr)
150
{
151
rte_ticketlock_init
(&tlr->tl);
152
rte_atomic_store_explicit(&tlr->user,
TICKET_LOCK_INVALID_ID
, rte_memory_order_relaxed);
153
tlr->count = 0;
154
}
155
162
static
inline
void
163
rte_ticketlock_recursive_lock
(rte_ticketlock_recursive_t *tlr)
164
{
165
int
id
=
rte_gettid
();
166
167
if
(rte_atomic_load_explicit(&tlr->user, rte_memory_order_relaxed) !=
id
) {
168
rte_ticketlock_lock
(&tlr->tl);
169
rte_atomic_store_explicit(&tlr->user,
id
, rte_memory_order_relaxed);
170
}
171
tlr->count++;
172
}
173
180
static
inline
void
181
rte_ticketlock_recursive_unlock
(rte_ticketlock_recursive_t *tlr)
182
{
183
if
(--(tlr->count) == 0) {
184
rte_atomic_store_explicit(&tlr->user,
TICKET_LOCK_INVALID_ID
,
185
rte_memory_order_relaxed);
186
rte_ticketlock_unlock
(&tlr->tl);
187
}
188
}
189
198
static
inline
int
199
rte_ticketlock_recursive_trylock
(rte_ticketlock_recursive_t *tlr)
200
{
201
int
id
=
rte_gettid
();
202
203
if
(rte_atomic_load_explicit(&tlr->user, rte_memory_order_relaxed) !=
id
) {
204
if
(
rte_ticketlock_trylock
(&tlr->tl) == 0)
205
return
0;
206
rte_atomic_store_explicit(&tlr->user,
id
, rte_memory_order_relaxed);
207
}
208
tlr->count++;
209
return
1;
210
}
211
212
#ifdef __cplusplus
213
}
214
#endif
215
216
#endif
/* _RTE_TICKETLOCK_H_ */
rte_common.h
rte_gettid
static int rte_gettid(void)
Definition
rte_eal.h:439
rte_lcore.h
rte_pause.h
rte_wait_until_equal_16
static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, rte_memory_order memorder)
Definition
rte_pause.h:84
TICKET_LOCK_INVALID_ID
#define TICKET_LOCK_INVALID_ID
Definition
rte_ticketlock.h:128
rte_ticketlock_recursive_init
static void rte_ticketlock_recursive_init(rte_ticketlock_recursive_t *tlr)
Definition
rte_ticketlock.h:149
rte_ticketlock_init
static void rte_ticketlock_init(rte_ticketlock_t *tl)
Definition
rte_ticketlock.h:52
rte_ticketlock_unlock
static void rte_ticketlock_unlock(rte_ticketlock_t *tl)
Definition
rte_ticketlock.h:78
rte_ticketlock_recursive_lock
static void rte_ticketlock_recursive_lock(rte_ticketlock_recursive_t *tlr)
Definition
rte_ticketlock.h:163
rte_ticketlock_lock
static void rte_ticketlock_lock(rte_ticketlock_t *tl)
Definition
rte_ticketlock.h:64
rte_ticketlock_recursive_unlock
static void rte_ticketlock_recursive_unlock(rte_ticketlock_recursive_t *tlr)
Definition
rte_ticketlock.h:181
rte_ticketlock_is_locked
static int rte_ticketlock_is_locked(rte_ticketlock_t *tl)
Definition
rte_ticketlock.h:118
rte_ticketlock_recursive_trylock
static int rte_ticketlock_recursive_trylock(rte_ticketlock_recursive_t *tlr)
Definition
rte_ticketlock.h:199
rte_ticketlock_trylock
static int rte_ticketlock_trylock(rte_ticketlock_t *tl)
Definition
rte_ticketlock.h:93
rte_ticketlock_t
Definition
rte_ticketlock.h:32
lib
eal
include
rte_ticketlock.h
Generated by
1.17.0