DPDK 26.07.0-rc1
rte_spinlock.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
3 */
4
5#ifndef _RTE_SPINLOCK_H_
6#define _RTE_SPINLOCK_H_
7
24#include <rte_lcore.h>
25#ifdef RTE_FORCE_INTRINSICS
26#include <rte_common.h>
27#endif
28#include <rte_debug.h>
29#include <rte_lock_annotations.h>
30#include <rte_pause.h>
31#include <rte_stdatomic.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
40typedef struct __rte_capability("spinlock") {
41 volatile RTE_ATOMIC(int) locked;
43
47#define RTE_SPINLOCK_INITIALIZER { 0 }
48
55static inline void
57{
58 sl->locked = 0;
59}
60
67static inline void
69 __rte_acquire_capability(sl);
70
71#ifdef RTE_FORCE_INTRINSICS
72static inline void
74 __rte_no_thread_safety_analysis
75{
76 int exp = 0;
77
78 while (!rte_atomic_compare_exchange_strong_explicit(&sl->locked, &exp, 1,
79 rte_memory_order_acquire, rte_memory_order_relaxed)) {
80 rte_wait_until_equal_32((volatile uint32_t *)(uintptr_t)&sl->locked,
81 0, rte_memory_order_relaxed);
82 exp = 0;
83 }
84}
85#endif
86
93static inline void
95 __rte_release_capability(sl);
96
97#ifdef RTE_FORCE_INTRINSICS
98static inline void
100 __rte_no_thread_safety_analysis
101{
102 rte_atomic_store_explicit(&sl->locked, 0, rte_memory_order_release);
103}
104#endif
105
115static inline int
117 __rte_try_acquire_capability(true, sl);
118
119#ifdef RTE_FORCE_INTRINSICS
120static inline int
122 __rte_no_thread_safety_analysis
123{
124 int exp = 0;
125 return rte_atomic_compare_exchange_strong_explicit(&sl->locked, &exp, 1,
126 rte_memory_order_acquire, rte_memory_order_relaxed);
127}
128#endif
129
139{
140 return rte_atomic_load_explicit(&sl->locked, rte_memory_order_acquire);
141}
142
149static inline int rte_tm_supported(void);
150
164static inline void
166 __rte_acquire_capability(sl);
167
175static inline void
177 __rte_release_capability(sl);
178
196static inline int
198 __rte_try_acquire_capability(true, sl);
199
203typedef struct {
205 RTE_ATOMIC(int) owner;
206 int count;
208
212#define RTE_SPINLOCK_RECURSIVE_INITIALIZER {RTE_SPINLOCK_INITIALIZER, -1, 0}
213
221{
222 rte_spinlock_init(&slr->sl);
223 rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
224 slr->count = 0;
225}
226
234 __rte_no_thread_safety_analysis
235{
236 int id = rte_gettid();
237
238 if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
239 rte_spinlock_lock(&slr->sl);
240 rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
241 }
242 slr->count++;
243}
251 __rte_no_thread_safety_analysis
252{
253 RTE_ASSERT(rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) == rte_gettid());
254 RTE_ASSERT(slr->count > 0);
255 if (--(slr->count) == 0) {
256 rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
257 rte_spinlock_unlock(&slr->sl);
258 }
259}
260
271 __rte_no_thread_safety_analysis
272{
273 int id = rte_gettid();
274
275 if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
276 if (rte_spinlock_trylock(&slr->sl) == 0)
277 return 0;
278 rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
279 }
280 slr->count++;
281 return 1;
282}
283
284
300
310
330
331#ifdef __cplusplus
332}
333#endif
334
335#endif /* _RTE_SPINLOCK_H_ */
#define __rte_warn_unused_result
Definition: rte_common.h:481
static int rte_gettid(void)
Definition: rte_eal.h:439
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, rte_memory_order memorder)
Definition: rte_pause.h:95
static __rte_warn_unused_result int rte_spinlock_trylock(rte_spinlock_t *sl) sl)
static int rte_tm_supported(void)
static __rte_warn_unused_result int rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)
static void rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)
static void rte_spinlock_unlock(rte_spinlock_t *sl)
static void rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)
static void rte_spinlock_lock(rte_spinlock_t *sl)
static void rte_spinlock_lock_tm(rte_spinlock_t *sl)
static void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
Definition: rte_spinlock.h:220
static __rte_warn_unused_result int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:270
static void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:250
static void rte_spinlock_unlock_tm(rte_spinlock_t *sl)
static __rte_warn_unused_result int rte_spinlock_trylock_tm(rte_spinlock_t *sl) sl)
static int rte_spinlock_is_locked(rte_spinlock_t *sl)
Definition: rte_spinlock.h:138
static void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:233
static void rte_spinlock_init(rte_spinlock_t *sl)
Definition: rte_spinlock.h:56