#ifndef __FENNIX_KERNEL_ATOMIC_H__ #define __FENNIX_KERNEL_ATOMIC_H__ #define _Atomic(T) T #define builtin_atomic(name) __atomic_##name##_n namespace { enum MemoryBorder { Relaxed = __ATOMIC_RELAXED, Acquire = __ATOMIC_ACQUIRE, Release = __ATOMIC_RELEASE, AcqRel = __ATOMIC_ACQ_REL, SeqCst = __ATOMIC_SEQ_CST }; template class Atomic { _Atomic(T) Value; public: Atomic(T Init) : Value(Init) {} T Load(MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(load)(&Value, Order); } void Store(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(store)(&Value, v, Order); } T Exchange(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(exchange)(&Value, v, Order); } bool CompareExchange(T &Expected, T Desired, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(compare_exchange)(&Value, &Expected, Desired, true, Order, Order); } T FetchAdd(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(fetch_add)(&Value, v, Order); } T FetchSub(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(fetch_sub)(&Value, v, Order); } T FetchAnd(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(fetch_and)(&Value, v, Order); } T FetchOr(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(fetch_or)(&Value, v, Order); } T FetchXor(T v, MemoryBorder Order = MemoryBorder::SeqCst) { return builtin_atomic(fetch_xor)(&Value, v, Order); } T operator++() { return FetchAdd(1) + 1; } T operator++(int) { return FetchAdd(1); } T operator--() { return FetchSub(1) - 1; } T operator--(int) { return FetchSub(1); } T operator+=(T v) { return FetchAdd(v) + v; } T operator-=(T v) { return FetchSub(v) - v; } T operator&=(T v) { return FetchAnd(v) & v; } T operator|=(T v) { return FetchOr(v) | v; } T operator^=(T v) { return FetchXor(v) ^ v; } T operator=(T v) { Store(v); return v; } }; } #undef builtin_atomic #endif // !__FENNIX_KERNEL_ATOMIC_H__