DPDK 24.11.7
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_lock_annotations.h>
29#include <rte_pause.h>
30#include <rte_stdatomic.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
39typedef struct __rte_lockable {
40 volatile RTE_ATOMIC(int) locked;
42
46#define RTE_SPINLOCK_INITIALIZER { 0 }
47
54static inline void
56{
57 sl->locked = 0;
58}
59
66static inline void
68 __rte_exclusive_lock_function(sl);
69
70#ifdef RTE_FORCE_INTRINSICS
71static inline void
73 __rte_no_thread_safety_analysis
74{
75 int exp = 0;
76
77 while (!rte_atomic_compare_exchange_strong_explicit(&sl->locked, &exp, 1,
78 rte_memory_order_acquire, rte_memory_order_relaxed)) {
79 rte_wait_until_equal_32((volatile uint32_t *)(uintptr_t)&sl->locked,
80 0, rte_memory_order_relaxed);
81 exp = 0;
82 }
83}
84#endif
85
92static inline void
94 __rte_unlock_function(sl);
95
96#ifdef RTE_FORCE_INTRINSICS
97static inline void
99 __rte_no_thread_safety_analysis
100{
101 rte_atomic_store_explicit(&sl->locked, 0, rte_memory_order_release);
102}
103#endif
104
114static inline int
116 __rte_exclusive_trylock_function(1, sl);
117
118#ifdef RTE_FORCE_INTRINSICS
119static inline int
121 __rte_no_thread_safety_analysis
122{
123 int exp = 0;
124 return rte_atomic_compare_exchange_strong_explicit(&sl->locked, &exp, 1,
125 rte_memory_order_acquire, rte_memory_order_relaxed);
126}
127#endif
128
138{
139 return rte_atomic_load_explicit(&sl->locked, rte_memory_order_acquire);
140}
141
148static inline int rte_tm_supported(void);
149
163static inline void
165 __rte_exclusive_lock_function(sl);
166
174static inline void
176 __rte_unlock_function(sl);
177
195static inline int
197 __rte_exclusive_trylock_function(1, sl);
198
202typedef struct {
204 RTE_ATOMIC(int) owner;
205 int count;
207
211#define RTE_SPINLOCK_RECURSIVE_INITIALIZER {RTE_SPINLOCK_INITIALIZER, -1, 0}
212
220{
221 rte_spinlock_init(&slr->sl);
222 rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
223 slr->count = 0;
224}
225
233 __rte_no_thread_safety_analysis
234{
235 int id = rte_gettid();
236
237 if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
238 rte_spinlock_lock(&slr->sl);
239 rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
240 }
241 slr->count++;
242}
250 __rte_no_thread_safety_analysis
251{
252 if (--(slr->count) == 0) {
253 rte_atomic_store_explicit(&slr->owner, -1, rte_memory_order_relaxed);
254 rte_spinlock_unlock(&slr->sl);
255 }
256}
257
268 __rte_no_thread_safety_analysis
269{
270 int id = rte_gettid();
271
272 if (rte_atomic_load_explicit(&slr->owner, rte_memory_order_relaxed) != id) {
273 if (rte_spinlock_trylock(&slr->sl) == 0)
274 return 0;
275 rte_atomic_store_explicit(&slr->owner, id, rte_memory_order_relaxed);
276 }
277 slr->count++;
278 return 1;
279}
280
281
297
307
327
328#ifdef __cplusplus
329}
330#endif
331
332#endif /* _RTE_SPINLOCK_H_ */
#define __rte_warn_unused_result
Definition: rte_common.h:404
static int rte_gettid(void)
Definition: rte_eal.h:438
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:219
static __rte_warn_unused_result int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:267
static void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:249
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:137
static void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:232
static void rte_spinlock_init(rte_spinlock_t *sl)
Definition: rte_spinlock.h:55