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...@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.w...@arm.com>
Reviewed-by: Steve Capper <steve.cap...@arm.com>
Reviewed-by: Ola Liljedahl <ola.liljed...@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagaraha...@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

Reply via email to