std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit(3)

NAME
std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit - std::atomic_flag_test_and_set,std::atomic_flag_test_and_set_explicit

Synopsis
   Defined in header <atomic>
   bool atomic_flag_test_and_set( volatile std::atomic_flag* obj ) (1) (since C++11)
   noexcept;
   bool atomic_flag_test_and_set( std::atomic_flag* obj ) noexcept; (2) (since C++11)
   bool atomic_flag_test_and_set_explicit( volatile std::atomic_flag*
   obj, (3) (since C++11)
                        std::memory_order order )
   noexcept;
   bool atomic_flag_test_and_set_explicit( std::atomic_flag* obj,
                        std::memory_order order ) (4) (since C++11)
   noexcept;
   Atomically changes the state of a std::atomic_flag pointed to by obj to set (true)
   and returns the value it held before.
   1,2) The memory synchronization order is std::memory_order_seq_cst.
   3,4) The memory synchronization order is order.

Parameters
   obj - pointer to std::atomic_flag to access
   order - the memory synchronization order

Return value
   The value previously held by the flag pointed to by obj.

Notes
   std::atomic_flag_test_and_set and std::atomic_flag_test_and_set_explicit can be
   implemented as obj->test_and_set() and obj->test_and_set(order) respectively.

Example
   A spinlock mutex can be implemented in userspace using an std::atomic_flag. // Run this code
 #include <atomic>
 #include <iostream>
 #include <thread>
 #include <vector>
 std::atomic_flag lock = ATOMIC_FLAG_INIT;
 void f(int n)
 {
     for (int cnt = 0; cnt < 100; ++cnt)
     {
         while (std::atomic_flag_test_and_set_explicit(&lock, std::memory_order_acquire))
             ; // spin until the lock is acquired
         std::cout << "Output from thread " << n << '\n';
         std::atomic_flag_clear_explicit(&lock, std::memory_order_release);
     }
 }
 int main()
 {
     std::vector<std::thread> v;
     for (int n = 0; n < 10; ++n)
         v.emplace_back(f, n);
     for (auto& t : v)
         t.join();
 }

Output:
 Output from thread 2
 Output from thread 6
 Output from thread 7
 ...<exactly 1000 lines>...

See also
   atomic_flag the lock-free boolean atomic type
   (C++11) (class)
   atomic_flag_clear
   atomic_flag_clear_explicit atomically sets the value of the flag to false
   (C++11) (function)
   (C++11)
   memory_order defines memory ordering constraints for the given atomic
   (C++11) operation
                        (enum)
   C documentation for
   atomic_flag_test_and_set,
   atomic_flag_test_and_set_explicit