DPDK 21.11.9
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
28static inline void rte_pause(void);
29
44static __rte_always_inline void
45rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected,
46 int memorder);
47
62static __rte_always_inline void
63rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected,
64 int memorder);
65
80static __rte_always_inline void
81rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected,
82 int memorder);
83
84#ifndef RTE_WAIT_UNTIL_EQUAL_ARCH_DEFINED
85static __rte_always_inline void
86rte_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
95static __rte_always_inline void
96rte_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
105static __rte_always_inline void
106rte_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_ */
#define __rte_always_inline
Definition: rte_common.h:233
static __rte_always_inline void rte_wait_until_equal_64(volatile uint64_t *addr, uint64_t expected, int memorder)
Definition: rte_pause.h:106
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, int memorder)
Definition: rte_pause.h:96
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 void rte_pause(void)