Use atomic types and flags with `<stdatomic.h>`
masterC11 provides atomics to prevent data races.
Atomic Types
Use the _Atomic type specifier (or typedefs like atomic_int) to declare variables that are treated atomically. Ordinary read/write access to these types is sequentially consistent.
Atomic Flags
atomic_flag is a guaranteed lock-free, atomic boolean type. It is typically used for spinlocks via atomic_flag_test_and_set and atomic_flag_clear. Initialize them using ATOMIC_FLAG_INIT.
Atomic Variables
Atomic variables (declared with _Atomic) can be initialized using ATOMIC_VAR_INIT or atomic_init. Unlike flags, they are not guaranteed to be lock-free. They support advanced operations like atomic_compare_exchange_weak and atomic_store.
// Example: Spinlock using atomic_flag
struct spinlock
{
atomic_flag flag;
};
void acquire_spinlock(struct spinlock* lock)
{
while (atomic_flag_test_and_set(&lock->flag) == true);
}
void release_spinlock(struct spinlock* lock)
{
atomic_flag_clear(&lock->flag);
}
// Example: Spinlock using atomic_bool
struct spinlock_bool
{
atomic_bool flag;
};
void acquire_spinlock_bool(struct spinlock_bool* lock)
{
bool expected = false;
while (atomic_compare_exchange_weak(&lock->flag, &expected, true) == false)
{
expected = false;
}
}
void release_spinlock_bool(struct spinlock_bool* lock)
{
atomic_store(&lock->flag, false);
}