HOME
| OPENMP API Specification: Version 5.0 November 2018

2.17.7  atomic Construct

SummaryThe atomic construct ensures that a specific storage location is accessed atomically, rather than exposing it to the possibility of multiple, simultaneous reading and writing threads that may result in indeterminate values.

Syntax

In the following syntax, atomic-clause is a clause that indicates the semantics for which atomicity is enforced, memory-order-clause is a clause that indicates the memory ordering behavior of the construct and clause is a clause other than atomic-clause. Specifically, atomic-clause is one of the following:  

 
read 
write 
update 
capture  

memory-order-clause is one of the following:  

 
seq_cst 
acq_rel 
release 
acquire 
relaxed  

and clause is either memory-order-clause or one of the following:  

 
hint(hint-expression)  

SVG-Viewer needed.

The syntax of the atomic construct takes one of the following forms:  

 
#pragma omp atomic [clause[[[,] clause] ... ] [,]] atomic-clause 
                   [[,] clause [[[,] clause] ... ]] new-line 
    expression-stmt  

or  

 
#pragma omp atomic [clause[[,] clause] ... ] new-line 
    expression-stmt  

or  

 
#pragma omp atomic [clause[[[,] clause] ... ] [,]] capture 
                   [[,] clause [[[,] clause] ... ]] new-line 
    structured-block  

where expression-stmt is an expression statement with one of the following forms:

In the preceding expressions:

SVG-Viewer needed.

SVG-Viewer needed.

The syntax of the atomic construct takes any of the following forms:  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] read [[,] clause [[[,] clause] ... ]] 
    capture-statement 
[!$omp end atomic]  

or  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] write [[,] clause [[[,] clause] ... ]] 
    write-statement 
[!$omp end atomic]  

or  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] update [[,] clause [[[,] clause] ... ]] 
    update-statement 
[!$omp end atomic]  

or  

 
!$omp atomic [clause[[,] clause] ... ] 
    update-statement 
[!$omp end atomic]  

or  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] capture [[,] clause [[[,] clause] ... ]] 
    update-statement 
    capture-statement 
!$omp end atomic  

or  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] capture [[,] clause [[[,] clause] ... ]] 
    capture-statement 
    update-statement 
!$omp end atomic  

or  

 
!$omp atomic [clause[[[,] clause] ... ] [,]] capture [[,] clause [[[,] clause] ... ]] 
    capture-statement 
    write-statement 
!$omp end atomic  

where write-statement has the following form (if atomic-clause is capture or write):  

 
x = expr  

where capture-statement has the following form (if atomic-clause is capture or read):  

 
v = x  

and where update-statement has one of the following forms (if atomic-clause is update, capture, or not present):  

 
x = x operator expr 
 
x = expr operator x 
 
x = intrinsic_procedure_name (x, expr_list) 
 
x = intrinsic_procedure_name (expr_list, x)  

In the preceding statements:

SVG-Viewer needed.

BindingIf the size of x is 8, 16, 32, or 64 bits and x is aligned to a multiple of its size, the binding thread set for the atomic region is all threads on the device. Otherwise, the binding thread set for the atomic region is all threads in the contention group. atomic regions enforce exclusive access with respect to other atomic regions that access the same storage location x among all threads in the binding thread set without regard to the teams to which the threads belong.

Description If atomic-clause is not present on the construct, the behavior is as if the update clause is specified.

The atomic construct with the read clause results in an atomic read of the location designated by x regardless of the native machine word size.

The atomic construct with the write clause results in an atomic write of the location designated by x regardless of the native machine word size.

The atomic construct with the update clause results in an atomic update of the location designated by x using the designated operator or intrinsic. Only the read and write of the location designated by x are performed mutually atomically. The evaluation of expr or expr_list need not be atomic with respect to the read or write of the location designated by x. No task scheduling points are allowed between the read and the write of the location designated by x.

The atomic construct with the capture clause results in an atomic captured update — an atomic update of the location designated by x using the designated operator or intrinsic while also capturing the original or final value of the location designated by x with respect to the atomic update. The original or final value of the location designated by x is written in the location designated by v based on the base language semantics of structured block or statements of the atomic construct. Only the read and write of the location designated by x are performed mutually atomically. Neither the evaluation of expr or expr_list, nor the write to the location designated by v, need be atomic with respect to the read or write of the location designated by x. No task scheduling points are allowed between the read and the write of the location designated by x.

The atomic construct may be used to enforce memory consistency between threads, based on the guarantees provided by Section 1.4.6 on page 71. A strong flush on the location designated by x is performed on entry to and exit from the atomic operation, ensuring that the set of all atomic operations in the program applied to the same location has a total completion order. If the write, update, or capture clause is specified and the release, acq_rel, or seq_cst clause is specified then the strong flush on entry to the atomic operation is also a release flush. If the read or capture clause is specified and the acquire, acq_rel, or seq_cst clause is specified then the strong flush on exit from the atomic operation is also an acquire flush. Therefore, if memory-order-clause is specified and is not relaxed, release and/or acquire flush operations are implied and permit synchronization between the threads without the use of explicit flush directives.

For all forms of the atomic construct, any combination of two or more of these atomic constructs enforces mutually exclusive access to the locations designated by x among threads in the binding thread set. To avoid data races, all accesses of the locations designated by x that could potentially occur in parallel must be protected with an atomic construct.

atomic regions do not guarantee exclusive access with respect to any accesses outside of atomic regions to the same storage location x even if those accesses occur during a critical or ordered region, while an OpenMP lock is owned by the executing task, or during the execution of a reduction clause.

However, other OpenMP synchronization can ensure the desired exclusive access. For example, a barrier that follows a series of atomic updates to x guarantees that subsequent accesses do not form a race with the atomic accesses.

A compliant implementation may enforce exclusive access between atomic regions that update different storage locations. The circumstances under which this occurs are implementation defined.

If the storage location designated by x is not size-aligned (that is, if the byte alignment of x is not a multiple of the size of x), then the behavior of the atomic region is implementation defined.

If present, the hint clause gives the implementation additional information about the expected properties of the atomic operation that can optionally be used to optimize the implementation. The presence of a hint clause does not affect the semantics of the atomic construct, and all hints may be ignored. If no hint clause is specified, the effect is as if hint(omp_sync_hint_none) had been specified.

Execution Model EventsThe atomic-acquiring event occurs in the thread that encounters the atomic construct on entry to the atomic region before initiating synchronization for the region. The atomic-acquired event occurs in the thread that encounters the atomic construct after it enters the region, but before it executes the structured block of the atomic region.

The atomic-released event occurs in the thread that encounters the atomic construct after it completes any synchronization on exit from the atomic region.

Tool Callbacks A thread dispatches a registered ompt_callback_mutex_acquire callback for each occurrence of an atomic-acquiring event in that thread. This callback has the type signature ompt_callback_mutex_acquire_t.

A thread dispatches a registered ompt_callback_mutex_acquired callback for each occurrence of an atomic-acquired event in that thread. This callback has the type signature ompt_callback_mutex_t.

A thread dispatches a registered ompt_callback_mutex_released callback with ompt_mutex_atomic as the kind argument if practical, although a less specific kind may be used, for each occurrence of an atomic-released event in that thread. This callback has the type signature ompt_callback_mutex_t and occurs in the task that encounters the atomic construct.

RestrictionsThe following restrictions apply to the atomic construct:

SVG-Viewer needed.

SVG-Viewer needed.

SVG-Viewer needed.

SVG-Viewer needed.

Cross References