DPDK  24.11.0-rc3
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
23 extern "C" {
24 #endif
25 
32 static inline void rte_pause(void);
33 
46 static __rte_always_inline void
47 rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
48  rte_memory_order memorder);
49 
62 static __rte_always_inline void
63 rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
64  rte_memory_order memorder);
65 
78 static __rte_always_inline void
79 rte_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
83 static __rte_always_inline void
84 rte_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 
94 static __rte_always_inline void
95 rte_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 
105 static __rte_always_inline void
106 rte_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_16(volatile uint16_t *addr, uint16_t expected, rte_memory_order memorder)
Definition: rte_pause.h:84
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)