#ifndef HB_ATOMIC_HH
#define HB_ATOMIC_HH
#include "hb.hh"
#include "hb-meta.hh"
#if defined(hb_atomic_int_impl_add) \
&& defined(hb_atomic_ptr_impl_get) \
&& defined(hb_atomic_ptr_impl_cmpexch)
#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
#define _hb_memory_barrier() …
#define hb_atomic_int_impl_add(AI, V) …
#define hb_atomic_int_impl_set_relaxed(AI, V) …
#define hb_atomic_int_impl_set(AI, V) …
#define hb_atomic_int_impl_get_relaxed(AI) …
#define hb_atomic_int_impl_get(AI) …
#define hb_atomic_ptr_impl_set_relaxed(P, V) …
#define hb_atomic_ptr_impl_get_relaxed(P) …
#define hb_atomic_ptr_impl_get(P) …
static inline bool
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
{ … }
#define hb_atomic_ptr_impl_cmpexch(P,O,N) …
#elif !defined(HB_NO_MT)
#include <atomic>
#define _hb_memory_barrier …
#define _hb_memory_r_barrier …
#define _hb_memory_w_barrier …
#define hb_atomic_int_impl_add …
#define hb_atomic_int_impl_set_relaxed …
#define hb_atomic_int_impl_set …
#define hb_atomic_int_impl_get_relaxed …
#define hb_atomic_int_impl_get …
#define hb_atomic_ptr_impl_set_relaxed …
#define hb_atomic_ptr_impl_get_relaxed …
#define hb_atomic_ptr_impl_get …
static inline bool
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
{
const void *O = O_;
return reinterpret_cast<std::atomic<const void*> *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed);
}
#define hb_atomic_ptr_impl_cmpexch …
#else
#define hb_atomic_int_impl_add …
#define _hb_memory_barrier …
#define hb_atomic_ptr_impl_cmpexch …
#endif
#ifndef _hb_compiler_memory_r_barrier
#if defined(__ATOMIC_ACQUIRE)
static inline void _hb_compiler_memory_r_barrier () { … }
#elif !defined(_MSC_VER)
#include <atomic>
#define _hb_compiler_memory_r_barrier …
#else
static inline void _hb_compiler_memory_r_barrier () {}
#endif
#endif
#ifndef _hb_memory_r_barrier
#define _hb_memory_r_barrier() …
#endif
#ifndef _hb_memory_w_barrier
#define _hb_memory_w_barrier() …
#endif
#ifndef hb_atomic_int_impl_set_relaxed
#define hb_atomic_int_impl_set_relaxed …
#endif
#ifndef hb_atomic_int_impl_get_relaxed
#define hb_atomic_int_impl_get_relaxed …
#endif
#ifndef hb_atomic_ptr_impl_set_relaxed
#define hb_atomic_ptr_impl_set_relaxed …
#endif
#ifndef hb_atomic_ptr_impl_get_relaxed
#define hb_atomic_ptr_impl_get_relaxed …
#endif
#ifndef hb_atomic_int_impl_set
inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; }
inline void hb_atomic_int_impl_set (short *AI, short v) { _hb_memory_w_barrier (); *AI = v; }
#endif
#ifndef hb_atomic_int_impl_get
inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; }
inline short hb_atomic_int_impl_get (const short *AI) { short v = *AI; _hb_memory_r_barrier (); return v; }
#endif
#ifndef hb_atomic_ptr_impl_get
inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; }
#endif
struct hb_atomic_short_t
{ … };
struct hb_atomic_int_t
{ … };
template <typename P>
struct hb_atomic_ptr_t
{ … };
static inline bool hb_barrier ()
{ … }
#endif