home | help
std::atomic_thread_fence(3)    C++ Standard Libary   std::atomic_thread_fence(3)

NAME
     std::atomic_thread_fence - std::atomic_thread_fence

Synopsis
	Defined in header <atomic>
	extern	 "C"   void   atomic_thread_fence(   std::memory_order	order  )
     (since C++11)
	noexcept;

	Establishes memory synchronization ordering of	non-atomic  and  relaxed
     atomic
	accesses,  as  instructed  by order, without an associated atomic opera-
     tion. Note
	however, that at least one atomic operation is required to set up the
	synchronization, as described below.

Parameters
	order - the memory ordering executed by this fence

Return value
	(none)

Notes
	On x86 (including x86-64), atomic_thread_fence functions  issue  no  CPU
     instructions
	and only affect compile-time code motion, except for
	std::atomic_thread_fence(std::memory_order::seq_cst).

	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 reads and writes from moving past the
	store-release, an atomic_thread_fence with memory_order_release ordering
     prevents
	all preceding reads and writes from moving past all subsequent stores.

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

      // Global
      std::string computation(int);
      void print(std::string);

      std::atomic<int> arr[3] = {-1, -1, -1};
      std::string data[1000]; //non-atomic data

      // Thread A, compute 3 values.
      void ThreadA(int v0, int v1, int v2)
      {
      //  assert(0 <= v0, v1, v2 < 1000);
	  data[v0] = computation(v0);
	  data[v1] = computation(v1);
	  data[v2] = computation(v2);
	  std::atomic_thread_fence(std::memory_order_release);
	  std::atomic_store_explicit(&arr[0], v0, std::memory_order_relaxed);
	  std::atomic_store_explicit(&arr[1], v1, std::memory_order_relaxed);
	  std::atomic_store_explicit(&arr[2], v2, std::memory_order_relaxed);
      }

      // Thread B, prints between 0 and 3 values already computed.
      void ThreadB()
      {
	  int	v0  =  std::atomic_load_explicit(&arr[0],  std::memory_order_re-
     laxed);
	  int  v1  =  std::atomic_load_explicit(&arr[1],   std::memory_order_re-
     laxed);
	  int	v2  =  std::atomic_load_explicit(&arr[2],  std::memory_order_re-
     laxed);
	  std::atomic_thread_fence(std::memory_order_acquire);
      //  v0, v1, v2 might turn out to be -1, some or all of them.
      //  Otherwise it is safe to  read  the  non-atomic  data	because  of  the
     fences:
	  if (v0 != -1)
	      print(data[v0]);
	  if (v1 != -1)
	      print(data[v1]);
	  if (v2 != -1)
	      print(data[v2]);
      }

Example
	Scan  an  array of mailboxes, and process only the ones intended for us,
     without
	unnecessary synchronization. This example uses atomic-fence synchroniza-
     tion.

      const int num_mailboxes = 32;
      std::atomic<int> mailbox_receiver[num_mailboxes];
      std::string mailbox_data[num_mailboxes];

      // The writer threads update non-atomic shared data
      // and then update mailbox_receiver[i] as follows:
      mailbox_data[i] = ...;
      std::atomic_store_explicit(&mailbox_receiver[i],	receiver_id,   std::mem-
     ory_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_receiver[i],
	      std::memory_order_relaxed) == my_id)
	  {
	      // synchronize with just one writer
	      std::atomic_thread_fence(std::memory_order_acquire);
	      // guaranteed to observe everything done in the writer thread
	      // before the atomic_store_explicit()
	      do_work(mailbox_data[i]);
	  }

See also
	memory_order	    defines memory ordering constraints  for  the  given
     atomic
	(C++11) 	    operation
			    (enum)
	atomic_signal_fence fence between a thread and a signal handler executed
     in the same
	(C++11) 	    thread
			    (function)
	C documentation for
	atomic_thread_fence

http://cppreference.com 	   2024.06.10	     std::atomic_thread_fence(3)

home | help