DPDK  24.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 
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 
28 static inline void rte_pause(void);
29 
42 static __rte_always_inline void
43 rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
44  rte_memory_order memorder);
45 
58 static __rte_always_inline void
59 rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
60  rte_memory_order memorder);
61 
74 static __rte_always_inline void
75 rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
76  rte_memory_order memorder);
77 
78 #ifndef RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED
79 static __rte_always_inline void
80 rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
81  rte_memory_order memorder)
82 {
83  assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
84 
85  while (rte_atomic_load_explicit((volatile __rte_atomic uint16_t *)addr, memorder)
86  != expected)
87  rte_pause();
88 }
89 
90 static __rte_always_inline void
91 rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
92  rte_memory_order memorder)
93 {
94  assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
95 
96  while (rte_atomic_load_explicit((volatile __rte_atomic uint32_t *)addr, memorder)
97  != expected)
98  rte_pause();
99 }
100 
101 static __rte_always_inline void
102 rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
103  rte_memory_order memorder)
104 {
105  assert(memorder == rte_memory_order_acquire || memorder == rte_memory_order_relaxed);
106 
107  while (rte_atomic_load_explicit((volatile __rte_atomic uint64_t *)addr, memorder)
108  != expected)
109  rte_pause();
110 }
111 
112 /*
113  * Wait until *addr & mask makes the condition true. With a relaxed memory
114  * ordering model, the loads around this helper can be reordered.
115  *
116  * @param addr
117  * A pointer to the memory location.
118  * @param mask
119  * A mask of value bits in interest.
120  * @param cond
121  * A symbol representing the condition.
122  * @param expected
123  * An expected value to be in the memory location.
124  * @param memorder
125  * Two different memory orders that can be specified:
126  * rte_memory_order_acquire and rte_memory_order_relaxed.
127  */
128 #define RTE_WAIT_UNTIL_MASKED(addr, mask, cond, expected, memorder) do { \
129  RTE_BUILD_BUG_ON(!__builtin_constant_p(memorder)); \
130  RTE_BUILD_BUG_ON((memorder) != rte_memory_order_acquire && \
131  (memorder) != rte_memory_order_relaxed); \
132  typeof(*(addr)) expected_value = (expected); \
133  while (!((rte_atomic_load_explicit((addr), (memorder)) & (mask)) \
134  cond expected_value)) \
135  rte_pause(); \
136 } while (0)
137 #endif /* ! RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED */
138 
139 #endif /* _RTE_PAUSE_H_ */
#define __rte_always_inline
Definition: rte_common.h:355
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:91
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:80
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:102
static void rte_pause(void)