DPDK  20.08.0
rte_rwlock.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_RWLOCK_H_
6 #define _RTE_RWLOCK_H_
7 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #include <rte_common.h>
25 #include <rte_atomic.h>
26 #include <rte_pause.h>
27 
33 typedef struct {
34  volatile int32_t cnt;
35 } rte_rwlock_t;
36 
40 #define RTE_RWLOCK_INITIALIZER { 0 }
41 
48 static inline void
50 {
51  rwl->cnt = 0;
52 }
53 
60 static inline void
62 {
63  int32_t x;
64  int success = 0;
65 
66  while (success == 0) {
67  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
68  /* write lock is held */
69  if (x < 0) {
70  rte_pause();
71  continue;
72  }
73  success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1,
74  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
75  }
76 }
77 
91 __rte_experimental
92 static inline int
94 {
95  int32_t x;
96  int success = 0;
97 
98  while (success == 0) {
99  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
100  /* write lock is held */
101  if (x < 0)
102  return -EBUSY;
103  success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1,
104  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
105  }
106 
107  return 0;
108 }
109 
116 static inline void
118 {
119  __atomic_fetch_sub(&rwl->cnt, 1, __ATOMIC_RELEASE);
120 }
121 
135 __rte_experimental
136 static inline int
138 {
139  int32_t x;
140 
141  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
142  if (x != 0 || __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1,
143  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) == 0)
144  return -EBUSY;
145 
146  return 0;
147 }
148 
155 static inline void
157 {
158  int32_t x;
159  int success = 0;
160 
161  while (success == 0) {
162  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
163  /* a lock is held */
164  if (x != 0) {
165  rte_pause();
166  continue;
167  }
168  success = __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1,
169  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
170  }
171 }
172 
179 static inline void
181 {
182  __atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE);
183 }
184 
198 static inline void
200 
207 static inline void
209 
223 static inline void
225 
232 static inline void
234 
235 #ifdef __cplusplus
236 }
237 #endif
238 
239 #endif /* _RTE_RWLOCK_H_ */
static void rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
static void rte_rwlock_read_lock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:61
static void rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
static void rte_rwlock_read_unlock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:117
static void rte_pause(void)
volatile int32_t cnt
Definition: rte_rwlock.h:34
static __rte_experimental int rte_rwlock_read_trylock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:93
static void rte_rwlock_write_unlock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:180
static void rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
static void rte_rwlock_write_lock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:156
static void rte_rwlock_init(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:49
static void rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
static __rte_experimental int rte_rwlock_write_trylock(rte_rwlock_t *rwl)
Definition: rte_rwlock.h:137