DPDK  23.07.0
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 #include <rte_common.h>
18 #include <rte_atomic.h>
19 
26 static inline void rte_pause(void);
27 
42 static __rte_always_inline void
43 rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
44  int memorder);
45 
60 static __rte_always_inline void
61 rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
62  int memorder);
63 
78 static __rte_always_inline void
79 rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
80  int 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  int memorder)
86 {
87  assert(memorder == __ATOMIC_ACQUIRE || memorder == __ATOMIC_RELAXED);
88 
89  while (__atomic_load_n(addr, memorder) != expected)
90  rte_pause();
91 }
92 
93 static __rte_always_inline void
94 rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
95  int memorder)
96 {
97  assert(memorder == __ATOMIC_ACQUIRE || memorder == __ATOMIC_RELAXED);
98 
99  while (__atomic_load_n(addr, memorder) != expected)
100  rte_pause();
101 }
102 
103 static __rte_always_inline void
104 rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
105  int memorder)
106 {
107  assert(memorder == __ATOMIC_ACQUIRE || memorder == __ATOMIC_RELAXED);
108 
109  while (__atomic_load_n(addr, memorder) != expected)
110  rte_pause();
111 }
112 
113 /*
114  * Wait until *addr & mask makes the condition true. With a relaxed memory
115  * ordering model, the loads around this helper can be reordered.
116  *
117  * @param addr
118  * A pointer to the memory location.
119  * @param mask
120  * A mask of value bits in interest.
121  * @param cond
122  * A symbol representing the condition.
123  * @param expected
124  * An expected value to be in the memory location.
125  * @param memorder
126  * Two different memory orders that can be specified:
127  * __ATOMIC_ACQUIRE and __ATOMIC_RELAXED. These map to
128  * C++11 memory orders with the same names, see the C++11 standard or
129  * the GCC wiki on atomic synchronization for detailed definition.
130  */
131 #define RTE_WAIT_UNTIL_MASKED(addr, mask, cond, expected, memorder) do { \
132  RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); \
133  RTE_BUILD_BUG_ON(memorder != __ATOMIC_ACQUIRE && \
134  memorder != __ATOMIC_RELAXED); \
135  typeof(*(addr)) expected_value = (expected); \
136  while (!((__atomic_load_n((addr), (memorder)) & (mask)) cond \
137  expected_value)) \
138  rte_pause(); \
139 } while (0)
140 #endif /* ! RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED */
141 
142 #endif /* _RTE_PAUSE_H_ */
static __rte_always_inline void rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, int memorder)
Definition: rte_pause.h:104
#define __rte_always_inline
Definition: rte_common.h:255
static void rte_pause(void)
static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, int memorder)
Definition: rte_pause.h:84
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, int memorder)
Definition: rte_pause.h:94