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