DPDK 22.11.7
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
27static inline void rte_pause(void);
28
43static __rte_always_inline void
44rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
45 int memorder);
46
61static __rte_always_inline void
62rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
63 int memorder);
64
79static __rte_always_inline void
80rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
81 int memorder);
82
83#ifndef RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED
84static __rte_always_inline void
85rte_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
94static __rte_always_inline void
95rte_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
104static __rte_always_inline void
105rte_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_ */
#define __rte_always_inline
Definition: rte_common.h:255
static __rte_always_inline void rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, int memorder)
Definition: rte_pause.h:105
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, int memorder)
Definition: rte_pause.h:95
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 void rte_pause(void)