std::atomic_flag is a Boolean atomic that is guaranteed to be lock-free. It starts clear when initialized with ATOMIC_FLAG_INIT and cannot be copied or assigned. section 5.2.1 section 5.2.2
Its interface has just two state-changing operations:
- clear() resets the flag. It is a store, so it cannot use memory_order_acquire or memory_order_acq_rel; its default order is memory_order_seq_cst. section 5.2.2
- test_and_set() sets the flag and returns its previous value. It is a read-modify-write operation and accepts any memory-order tag; its default is memory_order_seq_cst. section 5.2.2
Listing 5.1. Implementation of a spinlock mutex using std::atomic_flag
class spinlock_mutex
{
std::atomic_flag flag;
public:
spinlock_mutex():
flag(ATOMIC_FLAG_INIT)
{}
void lock()
{
while(flag.test_and_set(std::memory_order_acquire));
}
void unlock()
{
flag.clear(std::memory_order_release);
}
};
A spinlock uses test_and_set() with acquire ordering to keep waiting while the flag is set, then clear() with release ordering to unlock. section 5.2.2

