+#ifndef PIPE_NATIVE_ATOMIC_XCHG
+static inline uint32_t p_atomic_xchg_32(uint32_t *v, uint32_t i)
+{
+ uint32_t actual = p_atomic_read(v);
+ uint32_t expected;
+ do {
+ expected = actual;
+ actual = p_atomic_cmpxchg(v, expected, i);
+ } while (expected != actual);
+ return actual;
+}
+
+static inline uint64_t p_atomic_xchg_64(uint64_t *v, uint64_t i)
+{
+ uint64_t actual = p_atomic_read(v);
+ uint64_t expected;
+ do {
+ expected = actual;
+ actual = p_atomic_cmpxchg(v, expected, i);
+ } while (expected != actual);
+ return actual;
+}
+
+#define p_atomic_xchg(v, i) ((__typeof(*(v))) \
+ sizeof(*(v)) == sizeof(uint32_t) ? p_atomic_xchg_32((uint32_t *)(v), (uint32_t)(i)) : \
+ sizeof(*(v)) == sizeof(uint64_t) ? p_atomic_xchg_64((uint64_t *)(v), (uint64_t)(i)) : \
+ (assert(!"should not get here"), 0))
+#endif