DPDK  19.05.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 static inline __rte_experimental int
93 {
94  int32_t x;
95  int success = 0;
96 
97  while (success == 0) {
98  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
99  /* write lock is held */
100  if (x < 0)
101  return -EBUSY;
102  success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1,
103  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
104  }
105 
106  return 0;
107 }
108 
115 static inline void
117 {
118  __atomic_fetch_sub(&rwl->cnt, 1, __ATOMIC_RELEASE);
119 }
120 
134 static inline __rte_experimental int
136 {
137  int32_t x;
138 
139  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
140  if (x != 0 || __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1,
141  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) == 0)
142  return -EBUSY;
143 
144  return 0;
145 }
146 
153 static inline void
155 {
156  int32_t x;
157  int success = 0;
158 
159  while (success == 0) {
160  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
161  /* a lock is held */
162  if (x != 0) {
163  rte_pause();
164  continue;
165  }
166  success = __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1,
167  __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
168  }
169 }
170 
177 static inline void
179 {
180  __atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE);
181 }
182 
196 static inline void
198 
205 static inline void
207 
221 static inline void
223 
230 static inline void
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif /* _RTE_RWLOCK_H_ */