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