DPDK 25.03.0-rc0
rte_pause.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Cavium, Inc
3 * Copyright(c) 2019 Arm Limited
4 */
5
6#ifndef _RTE_PAUSE_H_
7#define _RTE_PAUSE_H_
8
15#include <stdint.h>
16#include <assert.h>
17
18#include <rte_common.h>
19#include <rte_atomic.h>
20#include <rte_stdatomic.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
32static inline void rte_pause(void);
33
46static __rte_always_inline void
47rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
48 rte_memory_order memorder);
49
62static __rte_always_inline void
63rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
64 rte_memory_order memorder);
65
78static __rte_always_inline void
79rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
80 rte_memory_order memorder);
81
82#ifndef RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED
83static __rte_always_inline void
84rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
85 rte_memory_order memorder)
86{
87 assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
88
89 while (rte_atomic_load_explicit((volatile __rte_atomic uint16_t *)addr, memorder)
90 != expected)
91 rte_pause();
92}
93
94static __rte_always_inline void
95rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
96 rte_memory_order memorder)
97{
98 assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
99
100 while (rte_atomic_load_explicit((volatile __rte_atomic uint32_t *)addr, memorder)
101 != expected)
102 rte_pause();
103}
104
105static __rte_always_inline void
106rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
107 rte_memory_order memorder)
108{
109 assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
110
111 while (rte_atomic_load_explicit((volatile __rte_atomic uint64_t *)addr, memorder)
112 != expected)
113 rte_pause();
114}
115
116/*
117 * Wait until *addr & mask makes the condition true. With a relaxed memory
118 * ordering model, the loads around this helper can be reordered.
119 *
120 * @param addr
121 * A pointer to the memory location.
122 * @param mask
123 * A mask of value bits in interest.
124 * @param cond
125 * A symbol representing the condition.
126 * @param expected
127 * An expected value to be in the memory location.
128 * @param memorder
129 * Two different memory orders that can be specified:
130 * rte_memory_order_acquire and rte_memory_order_relaxed.
131 */
132#define RTE_WAIT_UNTIL_MASKED(addr, mask, cond, expected, memorder) do { \
133 RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); \
134 RTE_BUILD_BUG_ON((memorder) != rte_memory_order_acquire && \
135 (memorder) != rte_memory_order_relaxed); \
136 typeof(*(addr)) expected_value = (expected); \
137 while (!((rte_atomic_load_explicit((addr), (memorder)) & (mask)) \
138 cond expected_value)) \
139 rte_pause(); \
140} while (0)
141#endif /* ! RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED */
142
143#ifdef __cplusplus
144}
145#endif
146
147#endif /* _RTE_PAUSE_H_ */
#define __rte_always_inline
Definition: rte_common.h:413
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, rte_memory_order memorder)
Definition: rte_pause.h:95
static __rte_always_inline void rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, rte_memory_order memorder)
Definition: rte_pause.h:106
static void rte_pause(void)
static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, rte_memory_order memorder)
Definition: rte_pause.h:84