CNDP  22.08.0
cne_rwlock.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2010-2022 Intel Corporation
3  */
4 
5 #ifndef _CNE_RWLOCK_H_
6 #define _CNE_RWLOCK_H_
7 
20 #include <cne_branch_prediction.h>
21 #include <cne_spinlock.h>
22 #include <cne_common.h>
23 #include <cne_pause.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
34 typedef struct {
35  volatile int32_t cnt;
36 } cne_rwlock_t;
37 
41 #define CNE_RWLOCK_INITIALIZER \
42  { \
43  0 \
44  }
45 
52 static inline void
54 {
55  rwl->cnt = 0;
56 }
57 
64 static inline void
66 {
67  int32_t x;
68  int success = 0;
69 
70  while (success == 0) {
71  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
72  /* write lock is held */
73  if (x < 0) {
74  cne_pause();
75  continue;
76  }
77  success = __atomic_compare_exchange_n(&rwl->cnt, &x, x + 1, 1, __ATOMIC_ACQUIRE,
78  __ATOMIC_RELAXED);
79  }
80 }
81 
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, __ATOMIC_ACQUIRE,
104  __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 
132 static inline int
134 {
135  int32_t x;
136 
137  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
138  if (x != 0 ||
139  __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED) == 0)
140  return -EBUSY;
141 
142  return 0;
143 }
144 
151 static inline void
153 {
154  int32_t x;
155  int success = 0;
156 
157  while (success == 0) {
158  x = __atomic_load_n(&rwl->cnt, __ATOMIC_RELAXED);
159  /* a lock is held */
160  if (x != 0) {
161  cne_pause();
162  continue;
163  }
164  success =
165  __atomic_compare_exchange_n(&rwl->cnt, &x, -1, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
166  }
167 }
168 
175 static inline void
177 {
178  __atomic_store_n(&rwl->cnt, 0, __ATOMIC_RELEASE);
179 }
180 
194 static inline void
196 {
197  if (likely(cne_try_tm(&rwl->cnt)))
198  return;
200 }
201 
208 static inline void
210 {
211  if (unlikely(rwl->cnt))
213  else
214  cne_xend();
215 }
216 
230 static inline void
232 {
233  if (likely(cne_try_tm(&rwl->cnt)))
234  return;
236 }
237 
244 static inline void
246 {
247  if (unlikely(rwl->cnt))
249  else
250  cne_xend();
251 }
252 
253 #ifdef __cplusplus
254 }
255 #endif
256 
257 #endif /* _CNE_RWLOCK_H_ */
#define likely(x)
#define unlikely(x)
static void cne_rwlock_read_lock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:65
static void cne_rwlock_read_unlock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:117
static void cne_rwlock_write_lock_tm(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:231
static int cne_rwlock_write_trylock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:133
static void cne_rwlock_write_unlock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:176
static void cne_rwlock_read_lock_tm(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:195
static void cne_rwlock_init(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:53
static void cne_rwlock_read_unlock_tm(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:209
static int cne_rwlock_read_trylock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:93
static void cne_rwlock_write_lock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:152
static void cne_rwlock_write_unlock_tm(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:245
volatile int32_t cnt
Definition: cne_rwlock.h:35