9.10.1 Conflict Check Policies
{
AI12-0267-1}
This subclause determines what checks are performed
relating to possible concurrent conflicting actions (see 9.10).
Syntax
Legality Rules
{
AI12-0267-1}
Each policy_identifier
shall be one of No_Parallel_Conflict_Checks, Known_Parallel_Conflict_Checks,
All_Parallel_Conflict_Checks, No_Tasking_Conflict_Checks, Known_Tasking_Conflict_Checks,
All_Tasking_Conflict_Checks, No_Conflict_Checks, Known_Conflict_Checks,
All_Conflict_Checks, or an implementation-defined conflict check policy.
If two policy_identifiers
are given, one shall include the word Parallel and one shall include
the word Tasking. If only one policy_identifier
is given, it shall not include the word Parallel or Tasking.
Implementation defined:
Implementation-defined conflict check
policies.
{
AI12-0267-1}
A pragma
Conflict_Check_Policy given in a declarative_part
or immediately within a package_specification
applies from the place of the pragma to the end of the innermost enclosing
declarative region. The region for a pragma
Conflict_Check_Policy given as a configuration pragma is the declarative
region for the entire compilation unit (or units) to which it applies.
{
AI12-0267-1}
{
AI12-0294-1}
{
AI12-0298-1}
If multiple Conflict_Check_Policy pragmas apply
to a given construct, the conflict check policy is determined by the
one in the innermost enclosing region. If no Conflict_Check_Policy pragma
applies to a construct, the policy is (All_Parallel_Conflict_Checks,
No_Tasking_Conflict_Checks) (see below).
To be honest: {
AI12-0294-1}
The region mentioned in this rule is the region
to which the policy pragma applies, and not the declarative region in
which the policy pragma appears. This distinction matters when there
are multiple policy pragmas in a single declarative region.
{
AI12-0267-1}
{
AI12-0298-1}
Certain potentially conflicting actions are disallowed
according to which conflict check policies apply at the place where the
action or actions occur, as follows:
No_Parallel_Conflict_Checks
This policy imposes no restrictions on concurrent
actions arising from parallel constructs.
No_Tasking_Conflict_Checks
This policy imposes no restrictions on concurrent
actions arising from tasking constructs.
Known_Parallel_Conflict_Checks
If this policy applies to two concurrent actions
appearing within parallel constructs, they are disallowed
if they are known to denote the same object (see 6.4.1)
with uses that conflict. For the purposes of this check, any parallel
loop may be presumed to involve multiple concurrent iterations. Also,
for the purposes of deciding whether two actions are concurrent, it is
enough for the logical threads of control in which they occur to be concurrent
at any point in their execution, unless all of the following are true:
the shared object
is volatile;
the two logical
threads of control are both known to also refer to a shared synchronized
object; and
each thread whose
potentially conflicting action updates the shared volatile object, also
updates this shared synchronized object.
Reason: To properly
synchronize two actions to prevent concurrency, a thread that does an
update of a volatile object must update a synchronized object afterwards
to indicate it has completed its update, and the other thread needs to
test the value of the synchronized object before it reads the updated
volatile object. In a parallel construct, “signaling” cannot
be used to prevent concurrency, since that generally requires some blocking,
so testing the value of the synchronized object would probably need to
use a busy-wait loop.
Known_Tasking_Conflict_Checks
If this policy applies to two concurrent actions
appearing within the same compilation unit, at least
one of which appears within a task body but not within a parallel construct,
they are disallowed if they are known to denote the same object (see
6.4.1) with uses that conflict, and neither
potentially signals the other (see 9.10).
For the purposes of this check, any named task type may be presumed to
have multiple instances. Also, for the purposes of deciding whether two
actions are concurrent, it is enough for the tasks in which they occur
to be concurrent at any point in their execution, unless all of the following
are true:
the shared object
is volatile;
the two tasks are
both known to also refer to a shared synchronized object; and
each task whose
potentially conflicting action updates the shared volatile object, also
updates this shared synchronized object.
Reason: To properly
synchronize two actions to prevent concurrency, a task that does an update
of a nonvolatile object must use signaling via a synchronized
object to indicate it has completed its update, and the other task needs
to be signaled by this action on the synchronized object before it reads
the updated nonvolatile object. In other words, to synchronize communication
via a nonvolatile object, signaling must be used. To synchronize communication
via a volatile object, an update of a shared synchronized object followed
by a read of the synchronized object in the other task can be sufficient.
All_Parallel_Conflict_Checks
This policy includes the restrictions imposed by
the Known_Parallel_Conflict_Checks policy, and in addition
disallows a parallel construct from reading or updating a variable that
is global to the construct, unless it is a synchronized object, or unless
the construct is a parallel loop, and the global variable is a part of
a component of an array denoted by an indexed component with at least
one index expression that statically denotes the loop parameter of the
loop_parameter_specification
or the chunk parameter of the parallel loop.
All_Tasking_Conflict_Checks
This policy includes the restrictions
imposed by the Known_Tasking_Conflict_Checks policy, and in addition
disallows a task body from reading or updating a variable that is global
to the task body, unless it is a synchronized object.
No_Conflict_Checks,
Known_Conflict_Checks, All_Conflict_Checks
These are shorthands for (No_Parallel_Conflict_Checks,
No_Tasking_Conflict_Checks), (Known_Parallel_Conflict_Checks,
Known_Tasking_Conflict_Checks), and (All_Parallel_Conflict_Checks,
All_Tasking_Conflict_Checks), respectively.
Static Semantics
{
AI12-0344-1}
For a subprogram, the following language-defined
representation aspect may be specified:
Parallel_Calls
The Parallel_Calls aspect is of type Boolean. The
specified value shall be static. The Parallel_Calls aspect
of an inherited primitive subprogram is True if Parallel_Calls is True
either for the corresponding subprogram of the progenitor type or for
any other inherited subprogram that it overrides. If not specified or
inherited as True, the Parallel_Calls aspect of a subprogram is False.
Specifying the Parallel_Calls
aspect to be True for a subprogram indicates that the subprogram can
be safely called in parallel. Conflict checks (if required by the Conflict_Check_Policy
in effect) are made on the subprogram assuming that multiple concurrent
calls exist.[ Such checks can then be omitted on a call of the subprogram
in a parallel iteration context.]
Aspect Description
for Parallel_Calls: Specifies
whether a given subprogram is expected to be called in parallel.
Implementation Permissions
{
AI12-0267-1}
{
AI12-0298-1}
When the conflict check policy Known_Parallel_Conflict_Checks
or All_Parallel_Conflict_Checks applies, the implementation may disallow
two concurrent actions appearing within parallel constructs if the implementation
can prove they will at run-time denote the same object with uses that
conflict. Similarly, when the conflict check policy Known_Tasking_Conflict_Checks
or All_Tasking_Conflict_Checks applies, the implementation may disallow
two concurrent actions, at least one of which appears within a task body
but not within a parallel construct, if the implementation can prove
they will at run-time denote the same object with uses that conflict.
Ramification: This
permission allows additional enforcement in instance bodies (where Legality
Rules aren't usually enforced), in subunits and their parents, and across
compilation units, if the implementation wishes.
Extensions to Ada 2012
{
AI12-0267-1}
Conflict check policies (and
the associated checks) are new.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe