[dpdk-dev] [RFC 1/5] eal: add the APIs to wait until equal
Gavin Hu
gavin.hu at arm.com
Sun Jun 30 18:21:12 CEST 2019
The rte_wait_until_equal_xxx APIs abstract the functionality of 'polling
for a memory location to become equal to a given value'.
Signed-off-by: Gavin Hu <gavin.hu at arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang at arm.com>
Reviewed-by: Steve Capper <steve.capper at arm.com>
Reviewed-by: Ola Liljedahl <ola.liljedahl at arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli at arm.com>
---
.../common/include/arch/arm/rte_pause_64.h | 143 +++++++++++++++++++++
lib/librte_eal/common/include/generic/rte_pause.h | 20 +++
2 files changed, 163 insertions(+)
diff --git a/lib/librte_eal/common/include/arch/arm/rte_pause_64.h b/lib/librte_eal/common/include/arch/arm/rte_pause_64.h
index 93895d3..0095da6 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_pause_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_pause_64.h
@@ -17,6 +17,149 @@ static inline void rte_pause(void)
asm volatile("yield" ::: "memory");
}
+#ifdef RTE_USE_WFE
+#define rte_wait_until_equal_relaxed(addr, expected) do {\
+ typeof(*addr) tmp; \
+ if (__builtin_constant_p((expected))) \
+ do { \
+ if (sizeof(*(addr)) == 16)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxrh %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 32)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxr %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 64)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxr %x0, %1\n" \
+ "cmp %x0, %x2\n" \
+ "bne 1b\n" \
+ : "=&r" (tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ } while (0); \
+ else \
+ do { \
+ if (sizeof(*(addr)) == 16)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxrh %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 32)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxr %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 64)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldxr %x0, %1\n" \
+ "cmp %x0, %x2\n" \
+ "bne 1b\n" \
+ : "=&r" (tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ } while (0); \
+} while (0)
+
+#define rte_wait_until_equal_acquire(addr, expected) do {\
+ typeof(*addr) tmp; \
+ if (__builtin_constant_p((expected))) \
+ do { \
+ if (sizeof(*(addr)) == 16)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxrh %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 32)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxr %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 64)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxr %x0, %1\n" \
+ "cmp %x0, %x2\n" \
+ "bne 1b\n" \
+ : "=&r" (tmp) \
+ : "Q"(*addr), "i"(expected) \
+ : "cc", "memory"); \
+ } while (0); \
+ else \
+ do { \
+ if (sizeof(*(addr)) == 16)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxrh %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 32)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxr %w0, %1\n" \
+ "cmp %w0, %w2\n" \
+ "bne 1b\n" \
+ : "=&r"(tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ else if (sizeof(*(addr)) == 64)\
+ asm volatile( \
+ "sevl\n" \
+ "1: wfe\n" \
+ "ldaxr %x0, %1\n" \
+ "cmp %x0, %x2\n" \
+ "bne 1b\n" \
+ : "=&r" (tmp) \
+ : "Q"(*addr), "r"(expected) \
+ : "cc", "memory"); \
+ } while (0); \
+} while (0)
+
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/common/include/generic/rte_pause.h b/lib/librte_eal/common/include/generic/rte_pause.h
index 52bd4db..c115b61 100644
--- a/lib/librte_eal/common/include/generic/rte_pause.h
+++ b/lib/librte_eal/common/include/generic/rte_pause.h
@@ -20,4 +20,24 @@
*/
static inline void rte_pause(void);
+#if !defined(RTE_USE_WFE)
+#define rte_wait_until_equal_relaxed(addr, expected) do {\
+ rte_pause(); \
+ } while (*(addr) != (expected))
+
+#ifdef RTE_USE_C11_MEM_MODEL
+#define rte_wait_until_equal_acquire(addr, expected) do {\
+ rte_pause(); \
+ } while (__atomic_load_n((addr), __ATOMIC_ACQUIRE) != (expected))
+#else
+#define rte_wait_until_equal_acquire(addr, expected) do {\
+ do {\
+ rte_pause(); \
+ } while (*(addr) != (expected)); \
+ rte_smp_rmb(); \
+ } while (0)
+#endif
+#endif
+
+
#endif /* _RTE_PAUSE_H_ */
--
2.7.4
More information about the dev
mailing list