\pagebreak
\chapter{Synchronization}
\label{chap:synchronization}

The \code{barrier} construct is a stand-alone directive that requires all threads
of a team (within a contention group) to execute the barrier and complete
execution of all tasks within the region, before continuing past the barrier.

The \code{critical} construct is a directive that contains a structured block. 
The construct allows only a single thread at a time to execute the structured block (region).
Multiple critical regions may exist in a parallel region, and may
act cooperatively (only one thread at a time in all \code{critical} regions),
or separately (only one thread at a time in each \code{critical} regions when
a unique name is supplied on each \code{critical} construct).
An optional (lock) \code{hint} clause may be specified on a named \code{critical} 
construct to provide the OpenMP runtime guidance in selection a locking 
mechanism.

On a finer scale the \code{atomic} construct allows only a single thread at 
a time to have atomic access to a storage location involving a single read, 
write, update or capture statement, and a limited number of combinations 
when specifying the \code{capture} \plc{atomic-clause} clause.  The
\plc{atomic-clause} clause is required for some expression statements, but is
not required for \code{update} statements. The \plc{memory-order} clause can be
used to specify the degree of memory ordering enforced by an \code{atomic}
construct. From weakest to strongest, they are \code{relaxed} (the default),
acquire and/or release clauses (specified with \code{acquire}, \code{release},
or \code{acq\_rel}), and \code{seq\_cst}.  Please see the details in the
\plc{atomic Construct} subsection of the \plc{Directives} chapter in the OpenMP
Specifications document.

% The following three sentences were stolen from the spec.
The \code{ordered} construct either specifies a structured block in a loop, 
simd, or loop SIMD region that will be executed in the order of the loop 
iterations.  The ordered construct sequentializes and orders the execution 
of ordered regions while allowing code outside the region to run in parallel.

Since OpenMP 4.5 the \code{ordered} construct can also be a stand-alone 
directive that specifies cross-iteration dependences in a doacross loop nest.  
The \code{depend} clause uses a \code{sink} \plc{dependence-type}, along with a 
iteration vector argument (vec) to indicate the iteration that satisfies the 
dependence.  The \code{depend} clause with a \code{source}
\plc{dependence-type} specifies dependence satisfaction.

The \code{flush} directive is a stand-alone construct for enforcing consistency
between a thread's view of memory and the view of memory for other threads (see
the Memory Model chapter of this document for more details). When the construct
is used with an explicit variable list, a \plc{strong flush} that forces a
thread's temporary view of memory to be consistent with the actual memory is
applied to all listed variables. When the construct is used without an explicit
variable list and without a \plc{memory-order} clause, a strong flush is
applied to all locally thread-visible data as defined by the base language, and
additionally the construct provides both acquire and release memory ordering
semantics.  When an explicit variable list is not present and a
\plc{memory-order} clause is present, the construct provides acquire and/or
release memory ordering semantics according to the \plc{memory-order} clause,
but no strong flush is performed. A resulting strong flush that applies to a
set of variables effectively ensures that no memory (load or store)
operation for the affected variables may be reordered across the \code{flush}
directive.

General-purpose routines provide mutual exclusion semantics through locks, 
represented by lock variables.  
The semantics allows a task to \plc{set}, and hence 
\plc{own} a lock, until it is \plc{unset} by the task that set it. A 
\plc{nestable} lock can be set multiple times by a task, and is used
when in code requires nested control of locks.  A \plc{simple lock} can
only be set once by the owning task. There are specific calls for the two
types of locks, and the variable of a specific lock type cannot be used by the
other lock type.  

Any explicit task will observe the synchronization prescribed in a 
\code{barrier} construct and an implied barrier.  Also, additional synchronizations 
are available for tasks.  All children of a task will wait at a \code{taskwait} (for 
their siblings to complete).  A \code{taskgroup} construct creates a region in which the
current task is suspended at the end of the region until all sibling tasks, 
and their descendants, have completed. 
Scheduling constraints on task execution can be prescribed by the \code{depend}
clause to enforce dependence on previously generated tasks.
More details on controlling task executions can be found in the \plc{Tasking} Chapter
in the OpenMP Specifications document. %(DO REF. RIGHT.)
