Namespaces
Variants
Views
Actions

std::atomic_thread_fence

From cppreference.com
< cpp‎ | atomic
Defined in header <atomic>
extern "C" void atomic_thread_fence( std::memory_order order );
(since C++11)

Establishes memory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed by order, without an associated atomic operation.

Contents

[edit] Fence-atomic synchronization

A release fence F in thread A synchronizes-with atomic acquire operation Y in thread B, if

  • there exists an atomic store X (with any memory order)
  • Y reads the value written by X (or the value would be written by release sequence headed by X if X were a release operation)
  • F is sequenced-before X in thread A

In this case, all non-atomic and relaxed atomic stores that happen-before X in thread A will be synchronized-with all non-atomic and relaxed atomic loads from the same locations made in thread B after F.

[edit] Atomic-fence synchronization

An atomic release operation X in thread A synchronizes-with an acquire fence F in thread B, if

  • there exists an atomic read Y (with any memory order)
  • Y reads the value written by X (or by the release sequence headed by X)
  • Y is sequenced-before F in thread B

In this case, all non-atomic and relaxed atomic stores that happen-before X in thread A will be synchronized-with all non-atomic and relaxed atomic loads from the same locations made in thread B after F.

[edit] Fence-fence synchronization

A release fence FA in thread A synchronizes-with an acquire fence FB in thread B, if

  • There exists an atomic object M,
  • There exists an atomic write X (with any memory order) that modifies M in thread A
  • FA is sequenced-before X in thread A
  • There exists an atomic read Y (with any memory order) in thread B
  • Y reads the value written by X (or the value would be written by release sequence headed by X if X were a release operation)
  • Y is sequenced-before FB in thread B

In this case, all non-atomic and relaxed atomic stores that happen-before FA in thread A will be synchronized-with all non-atomic and relaxed atomic loads from the same locations made in thread B after FB

[edit] Parameters

order - the memory ordering executed by this fence

[edit] Return value

(none)

[edit] Exceptions

noexcept specification:  
noexcept
  

[edit] Notes

atomic_thread_fence imposes stronger synchronization constraints than an atomic store operation with the same std::memory_order. While an atomic store-release operation prevents all preceding writes from moving past the store-release, an atomic_thread_fence with memory_order_release ordering prevents all preceding writes from moving past all subsequent stores.

Fence-fence synchronization can be used to add synchronization to a sequence of several relaxed atomic operations, for example

[edit] Examples

Scan an array of mailboxes, and process only the ones intended for us, without unnecessary synchronization.

This example uses atomic-fence synchronization.

const int num_mailboxes = 32;
std::atomic<int> mailbox[num_mailboxes];
 
// The writer threads update non-atomic shared data and then update mailbox[i] as follows
std::atomic_store_explicit(&mailbox[i], receiver_id, std::memory_order_release);
 
// Reader thread needs to check all mailbox[i], but only needs to sync with one
for (int i = 0; i < num_mailboxes; ++i) {
    if (std::atomic_load_explicit(&mailbox[i], std::memory_order_relaxed) == my_id) {
        std::atomic_thread_fence(std::memory_order_acquire); // synchronize with just one writer
        do_work(i); // guaranteed to observe everything done in the writer thread before
                    // the atomic_store_explicit()
    }
 }


[edit] See also

defines memory ordering constraints for the given atomic operation
(typedef) [edit]
fence between a thread and a signal handler executed in the same thread
(function) [edit]
C documentation for atomic_thread_fence