std::atomic_thread_fence

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. For example, all non-atomic and relaxed atomic stores that happen before a std::memory_order_release fence in thread A will be synchronized with non-atomic and relaxed atomic loads from the same locations made in thread B after an std::memory_order_acquire fence if there exist atomic operations X and Y, both operating on some atomic object M, such that the fence in thread A is sequenced before X, X modifies M, Y is sequenced before the fence in thread B, and Y reads the value written by X or a value written by any side effect in the hypothetical release sequence X would head if it were a release operation..

Parameters

order - the memory ordering executed by this fence

Return value

(none).

Exceptions

noexcept specification:
noexcept

Notes

atomic_thread_fence imposes different 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.

Examples

Scan an array of mailboxes, and process only the ones intended for us, without unnecessary 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()
    }
 }

See also

(C++11)
defines memory ordering constraints for the given atomic operation
(typedef)
fence between a thread and a signal handler executed in the same thread
(function)
C documentation for atomic_thread_fence
doc_CPP
2016-10-11 10:00:31
Comments
Leave a Comment

Please login to continue.