DPDK 22.11.5
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
9extern "C" {
10#endif
11
23#include <stdbool.h>
24#include <stdint.h>
25
26#include <rte_atomic.h>
28#include <rte_compat.h>
29
33typedef struct {
34 uint32_t sn;
36
40#define RTE_SEQCOUNT_INITIALIZER { .sn = 0 }
41
51__rte_experimental
52static inline void
54{
55 seqcount->sn = 0;
56}
57
104__rte_experimental
105static 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
150static inline bool
151rte_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
200static 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
231static 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 void rte_atomic_thread_fence(int memorder)
#define unlikely(x)
static __rte_experimental void rte_seqcount_write_end(rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:232
static __rte_experimental uint32_t rte_seqcount_read_begin(const rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:106
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
static __rte_experimental void rte_seqcount_write_begin(rte_seqcount_t *seqcount)
Definition: rte_seqcount.h:201