/* The builtins with explicit memory model are available since GCC 4.7. */
#define p_atomic_set(_v, _i) __atomic_store_n((_v), (_i), __ATOMIC_RELEASE)
#define p_atomic_read(_v) __atomic_load_n((_v), __ATOMIC_ACQUIRE)
+#define p_atomic_read_relaxed(_v) __atomic_load_n((_v), __ATOMIC_RELAXED)
#define p_atomic_dec_zero(v) (__atomic_sub_fetch((v), 1, __ATOMIC_ACQ_REL) == 0)
#define p_atomic_inc(v) (void) __atomic_add_fetch((v), 1, __ATOMIC_ACQ_REL)
#define p_atomic_dec(v) (void) __atomic_sub_fetch((v), 1, __ATOMIC_ACQ_REL)
#define p_atomic_set(_v, _i) (*(_v) = (_i))
#define p_atomic_read(_v) (*(_v))
+#define p_atomic_read_relaxed(_v) (*(_v))
#define p_atomic_dec_zero(v) (__sync_sub_and_fetch((v), 1) == 0)
#define p_atomic_inc(v) (void) __sync_add_and_fetch((v), 1)
#define p_atomic_dec(v) (void) __sync_sub_and_fetch((v), 1)
#define p_atomic_set(_v, _i) (*(_v) = (_i))
#define p_atomic_read(_v) (*(_v))
+#define p_atomic_read_relaxed(_v) (*(_v))
#define p_atomic_dec_zero(_v) (p_atomic_dec_return(_v) == 0)
#define p_atomic_inc(_v) ((void) p_atomic_inc_return(_v))
#define p_atomic_dec(_v) ((void) p_atomic_dec_return(_v))
#define p_atomic_set(_v, _i) (*(_v) = (_i))
#define p_atomic_read(_v) (*(_v))
+#define p_atomic_read_relaxed(_v) (*(_v))
#define p_atomic_dec_zero(_v) \
(p_atomic_dec_return(_v) == 0)
do_futex_fence_wait(struct util_queue_fence *fence,
bool timeout, int64_t abs_timeout)
{
- uint32_t v = fence->val;
+ uint32_t v = p_atomic_read_relaxed(&fence->val);
struct timespec ts;
ts.tv_sec = abs_timeout / (1000*1000*1000);
ts.tv_nsec = abs_timeout % (1000*1000*1000);
return false;
}
- v = fence->val;
+ v = p_atomic_read_relaxed(&fence->val);
}
return true;
static inline void
util_queue_fence_destroy(struct util_queue_fence *fence)
{
- assert(fence->val == 0);
+ assert(p_atomic_read_relaxed(&fence->val) == 0);
/* no-op */
}
static inline bool
util_queue_fence_is_signalled(struct util_queue_fence *fence)
{
- return fence->val == 0;
+ return p_atomic_read_relaxed(&fence->val) == 0;
}
#endif