diff --git a/wasmtime-wasi/sandboxed-system-primitives/src/refcount.h b/wasmtime-wasi/sandboxed-system-primitives/src/refcount.h index 51752bc9b1..a259104c10 100644 --- a/wasmtime-wasi/sandboxed-system-primitives/src/refcount.h +++ b/wasmtime-wasi/sandboxed-system-primitives/src/refcount.h @@ -13,14 +13,20 @@ #define REFCOUNT_H #include +#if !defined(__GNUC__) #include +#endif #include #include "locking.h" // Simple reference counter. struct LOCKABLE refcount { +#if defined(__GNUC__) + unsigned count; +#else atomic_uint count; +#endif }; #define PRODUCES(...) LOCKS_SHARED(__VA_ARGS__) NO_LOCK_ANALYSIS @@ -28,18 +34,30 @@ struct LOCKABLE refcount { // Initialize the reference counter. static void refcount_init(struct refcount *r, unsigned int count) PRODUCES(*r) { +#if defined(__GNUC__) + __atomic_store_n(&r->count, count, __ATOMIC_SEQ_CST); +#else atomic_init(&r->count, count); +#endif } // Increment the reference counter. static inline void refcount_acquire(struct refcount *r) PRODUCES(*r) { +#if defined(__GNUC__) + __atomic_fetch_add(&r->count, 1, __ATOMIC_ACQUIRE); +#else atomic_fetch_add_explicit(&r->count, 1, memory_order_acquire); +#endif } // Decrement the reference counter, returning whether the reference // dropped to zero. static inline bool refcount_release(struct refcount *r) CONSUMES(*r) { +#if defined(__GNUC__) + int old = __atomic_fetch_sub(&r->count, 1, __ATOMIC_RELEASE); +#else int old = atomic_fetch_sub_explicit(&r->count, 1, memory_order_release); +#endif assert(old != 0 && "Reference count becoming negative"); return old == 1; }