DPDK  25.11.3
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
33 extern "C" {
34 #endif
35 
39 typedef struct __rte_capability("spinlock") {
40  volatile RTE_ATOMIC(int) locked;
42 
46 #define RTE_SPINLOCK_INITIALIZER { 0 }
47 
54 static inline void
56 {
57  sl->locked = 0;
58 }
59 
66 static inline void
68  __rte_acquire_capability(sl);
69 
70 #ifdef RTE_FORCE_INTRINSICS
71 static 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 
92 static inline void
94  __rte_release_capability(sl);
95 
96 #ifdef RTE_FORCE_INTRINSICS
97 static 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 
114 static inline int
116  __rte_try_acquire_capability(true, sl);
117 
118 #ifdef RTE_FORCE_INTRINSICS
119 static 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 
137 static inline int rte_spinlock_is_locked (rte_spinlock_t *sl)
138 {
139  return rte_atomic_load_explicit(&sl->locked, rte_memory_order_acquire);
140 }
141 
148 static inline int rte_tm_supported(void);
149 
163 static inline void
165  __rte_acquire_capability(sl);
166 
174 static inline void
176  __rte_release_capability(sl);
177 
195 static inline int
197  __rte_try_acquire_capability(true, sl);
198 
202 typedef 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 
295 static inline void rte_spinlock_recursive_lock_tm(
297 
305 static inline void rte_spinlock_recursive_unlock_tm(
307 
325 static inline int rte_spinlock_recursive_trylock_tm(
327 
328 #ifdef __cplusplus
329 }
330 #endif
331 
332 #endif /* _RTE_SPINLOCK_H_ */
static __rte_warn_unused_result int rte_spinlock_trylock_tm(rte_spinlock_t *sl) sl)
static void rte_spinlock_recursive_lock_tm(rte_spinlock_recursive_t *slr)
static void rte_spinlock_lock(rte_spinlock_t *sl)
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 void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr) __rte_no_thread_safety_analysis
Definition: rte_spinlock.h:249
static __rte_warn_unused_result int rte_spinlock_recursive_trylock_tm(rte_spinlock_recursive_t *slr)
static void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
Definition: rte_spinlock.h:219
static void rte_spinlock_unlock(rte_spinlock_t *sl)
static void rte_spinlock_unlock_tm(rte_spinlock_t *sl)
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_init(rte_spinlock_t *sl)
Definition: rte_spinlock.h:55
static int rte_tm_supported(void)
static __rte_warn_unused_result int rte_spinlock_trylock(rte_spinlock_t *sl) sl)
static void rte_spinlock_recursive_unlock_tm(rte_spinlock_recursive_t *slr)
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_lock_tm(rte_spinlock_t *sl)
static int rte_gettid(void)
Definition: rte_eal.h:439
#define __rte_warn_unused_result
Definition: rte_common.h:493