DPDK  22.07.0
rte_seqcount.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2022 Ericsson AB
3  */
4 
5 #ifndef _RTE_SEQCOUNT_H_
6 #define _RTE_SEQCOUNT_H_
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
23 #include <stdbool.h>
24 #include <stdint.h>
25 
26 #include <rte_atomic.h>
27 #include <rte_branch_prediction.h>
28 #include <rte_compat.h>
29 
33 typedef struct {
34  uint32_t sn;
36 
40 #define RTE_SEQCOUNT_INITIALIZER { .sn = 0 }
41 
51 __rte_experimental
52 static inline void
54 {
55  seqcount->sn = 0;
56 }
57 
104 __rte_experimental
105 static inline uint32_t
107 {
108  /* __ATOMIC_ACQUIRE to prevent loads after (in program order)
109  * from happening before the sn load. Synchronizes-with the
110  * store release in rte_seqcount_write_end().
111  */
112  return __atomic_load_n(&seqcount->sn, __ATOMIC_ACQUIRE);
113 }
114 
149 __rte_experimental
150 static inline bool
151 rte_seqcount_read_retry(const rte_seqcount_t *seqcount, uint32_t begin_sn)
152 {
153  uint32_t end_sn;
154 
155  /* An odd sequence number means the protected data was being
156  * modified already at the point of the rte_seqcount_read_begin()
157  * call.
158  */
159  if (unlikely(begin_sn & 1))
160  return true;
161 
162  /* make sure the data loads happens before the sn load */
163  rte_atomic_thread_fence(__ATOMIC_ACQUIRE);
164 
165  end_sn = __atomic_load_n(&seqcount->sn, __ATOMIC_RELAXED);
166 
167  /* A writer incremented the sequence number during this read
168  * critical section.
169  */
170  return begin_sn != end_sn;
171 }
172 
199 __rte_experimental
200 static inline void
202 {
203  uint32_t sn;
204 
205  sn = seqcount->sn + 1;
206 
207  __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELAXED);
208 
209  /* __ATOMIC_RELEASE to prevent stores after (in program order)
210  * from happening before the sn store.
211  */
212  rte_atomic_thread_fence(__ATOMIC_RELEASE);
213 }
214 
230 __rte_experimental
231 static inline void
233 {
234  uint32_t sn;
235 
236  sn = seqcount->sn + 1;
237 
238  /* Synchronizes-with the load acquire in rte_seqcount_read_begin(). */
239  __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELEASE);
240 }
241 
242 #ifdef __cplusplus
243 }
244 #endif
245 
246 #endif /* _RTE_SEQCOUNT_H_ */
static __rte_experimental void rte_seqcount_init(rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:53
static __rte_experimental bool rte_seqcount_read_retry(const rte_seqcount_t *seqcount, uint32_t begin_sn)
Definition: rte_seqcount.h:151
#define unlikely(x)
static __rte_experimental void rte_seqcount_write_begin(rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:201
static __rte_experimental uint32_t rte_seqcount_read_begin(const rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:106
static void rte_atomic_thread_fence(int memorder)
static __rte_experimental void rte_seqcount_write_end(rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:232