std1.0.0-beta-7 SafeC docs

Source atomic.sc

View in the repository

// SafeC Standard Library — Atomics (C11 <stdatomic.h>-equivalent surface)
//
// atomic_load/store/fetch_*/exchange/cas below are SafeC compiler builtins
// (see Sema::checkCall's "Atomic built-ins" handling), not C library
// functions — unlike real C, they need no declaration from a system
// <stdatomic.h> at all, so this file (unlike real C11 code) works
// unmodified in --freestanding mode, where no hosted header is available.
#pragma once
#include <std/atomic.h>

namespace std {

inline int atomic_load_int(const &int addr) {
    unsafe { return atomic_load((const _Atomic int*)addr); }
}

inline void atomic_store_int(&int addr, int val) {
    unsafe { atomic_store((_Atomic int*)addr, val); }
}

inline int atomic_fetch_add_int(&int addr, int delta) {
    unsafe { return atomic_fetch_add((_Atomic int*)addr, delta); }
}

inline int atomic_fetch_sub_int(&int addr, int delta) {
    unsafe { return atomic_fetch_sub((_Atomic int*)addr, delta); }
}

inline int atomic_fetch_and_int(&int addr, int mask) {
    unsafe { return atomic_fetch_and((_Atomic int*)addr, mask); }
}

inline int atomic_fetch_or_int(&int addr, int mask) {
    unsafe { return atomic_fetch_or((_Atomic int*)addr, mask); }
}

inline int atomic_fetch_xor_int(&int addr, int mask) {
    unsafe { return atomic_fetch_xor((_Atomic int*)addr, mask); }
}

inline int atomic_exchange_int(&int addr, int val) {
    unsafe { return atomic_exchange((_Atomic int*)addr, val); }
}

inline int atomic_cas_int(&int addr, &int expected, int desired) {
    unsafe {
        return atomic_compare_exchange_strong(
            (_Atomic int*)addr, expected, desired);
    }
}

inline long long atomic_load_ll(const &long long addr) {
    unsafe { return atomic_load((const _Atomic long long*)addr); }
}

inline void atomic_store_ll(&long long addr, long long val) {
    unsafe { atomic_store((_Atomic long long*)addr, val); }
}

inline long long atomic_fetch_add_ll(&long long addr, long long delta) {
    unsafe { return atomic_fetch_add((_Atomic long long*)addr, delta); }
}

inline long long atomic_fetch_sub_ll(&long long addr, long long delta) {
    unsafe { return atomic_fetch_sub((_Atomic long long*)addr, delta); }
}

inline long long atomic_exchange_ll(&long long addr, long long val) {
    unsafe { return atomic_exchange((_Atomic long long*)addr, val); }
}

inline int atomic_cas_ll(&long long addr, &long long expected, long long desired) {
    unsafe {
        return atomic_compare_exchange_strong(
            (_Atomic long long*)addr, expected, desired);
    }
}

inline void atomic_thread_fence() {
    unsafe { atomic_fence(); }
}

// ── Typed atomics ─────────────────────────────────────────────────────────────
struct AtomicInt AtomicInt::new(int v) { struct AtomicInt a; a.v_ = v; return a; }
int  AtomicInt::load() const { return atomic_load_int(&self.v_); }
void AtomicInt::store(int v) { atomic_store_int(&self.v_, v); }
int  AtomicInt::fetch_add(int d) { return atomic_fetch_add_int(&self.v_, d); }
int  AtomicInt::fetch_sub(int d) { return atomic_fetch_sub_int(&self.v_, d); }
int  AtomicInt::exchange(int v) { return atomic_exchange_int(&self.v_, v); }
int  AtomicInt::compare_exchange(&int expected, int desired) { return atomic_cas_int(&self.v_, expected, desired); }

struct AtomicLong AtomicLong::new(long long v) { struct AtomicLong a; a.v_ = v; return a; }
long long AtomicLong::load() const { return atomic_load_ll(&self.v_); }
void      AtomicLong::store(long long v) { atomic_store_ll(&self.v_, v); }
long long AtomicLong::fetch_add(long long d) { return atomic_fetch_add_ll(&self.v_, d); }
long long AtomicLong::fetch_sub(long long d) { return atomic_fetch_sub_ll(&self.v_, d); }
long long AtomicLong::exchange(long long v) { return atomic_exchange_ll(&self.v_, v); }
int       AtomicLong::compare_exchange(&long long expected, long long desired) { return atomic_cas_ll(&self.v_, expected, desired); }

} // namespace std