Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

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  re-
       laxed atomic
	  accesses, as instructed by order, without an associated atomic oper-
       ation. 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  or-
       dering prevents
	  all  preceding  reads	 and  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:

	// 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_re-
       laxed);
	    std::atomic_store_explicit(&arr[1],	  v1,	 std::memory_order_re-
       laxed);
	    std::atomic_store_explicit(&arr[2],	   v2,	 std::memory_order_re-
       laxed);
	}

	// 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 synchro-
       nization.

	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::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_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 exe-
       cuted in	the same
	  (C++11)	      thread
			      (function)
	  C documentation for
	  atomic_thread_fence

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

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::atomic_thread_fence&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help