blob: a4a59fb499d6f19a834aaba4c04bfb9c8763f3de [file] [log] [blame]
/* SPDX-License-Identifier: MIT */
#ifndef LIBURING_BARRIER_H
#define LIBURING_BARRIER_H
/*
From the kernel documentation file refcount-vs-atomic.rst:
A RELEASE memory ordering guarantees that all prior loads and
stores (all po-earlier instructions) on the same CPU are completed
before the operation. It also guarantees that all po-earlier
stores on the same CPU and all propagated stores from other CPUs
must propagate to all other CPUs before the release operation
(A-cumulative property). This is implemented using
:c:func:`smp_store_release`.
An ACQUIRE memory ordering guarantees that all post loads and
stores (all po-later instructions) on the same CPU are
completed after the acquire operation. It also guarantees that all
po-later stores on the same CPU must propagate to all other CPUs
after the acquire operation executes. This is implemented using
:c:func:`smp_acquire__after_ctrl_dep`.
*/
#ifdef __cplusplus
#include <atomic>
template <typename T>
static inline void IO_URING_WRITE_ONCE(T &var, T val)
{
std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(&var),
val, std::memory_order_relaxed);
}
template <typename T>
static inline T IO_URING_READ_ONCE(const T &var)
{
return std::atomic_load_explicit(
reinterpret_cast<const std::atomic<T> *>(&var),
std::memory_order_relaxed);
}
template <typename T>
static inline void io_uring_smp_store_release(T *p, T v)
{
std::atomic_store_explicit(reinterpret_cast<std::atomic<T> *>(p), v,
std::memory_order_release);
}
template <typename T>
static inline T io_uring_smp_load_acquire(const T *p)
{
return std::atomic_load_explicit(
reinterpret_cast<const std::atomic<T> *>(p),
std::memory_order_acquire);
}
#else
#include <stdatomic.h>
#define IO_URING_WRITE_ONCE(var, val) \
atomic_store_explicit((_Atomic typeof(var) *)&(var), \
(val), memory_order_relaxed)
#define IO_URING_READ_ONCE(var) \
atomic_load_explicit((_Atomic typeof(var) *)&(var), \
memory_order_relaxed)
#define io_uring_smp_store_release(p, v) \
atomic_store_explicit((_Atomic typeof(*(p)) *)(p), (v), \
memory_order_release)
#define io_uring_smp_load_acquire(p) \
atomic_load_explicit((_Atomic typeof(*(p)) *)(p), \
memory_order_acquire)
#endif
#endif /* defined(LIBURING_BARRIER_H) */