Annotated Ada Reference Manual (Ada 202y Draft 1)Legal Information
Contents   Index   References   Search   Previous   Next 

9.10.1 Conflict Check Policies

1/5
{AI12-0267-1} This subclause determines what checks are performed relating to possible concurrent conflicting actions (see 9.10).

Syntax

2/5
{AI12-0267-1} {AI12-0298-1} The form of a pragma Conflict_Check_Policy is as follows:
3/5
  pragma Conflict_Check_Policy (policy_identifier[, policy_identifier]);
4/5
{AI12-0267-1} A pragma Conflict_Check_Policy is allowed only immediately within a declarative_part, a package_specification, or as a configuration pragma.

Legality Rules

5/5
{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.
5.a.1/5
Implementation defined: Implementation-defined conflict check policies.
6/5
{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.
7/5
{AI12-0267-1} If a pragma Conflict_Check_Policy applies to a generic_instantiation, then the pragma Conflict_Check_Policy applies to the entire instance.
8/5
{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).
8.a/5
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. 
9/5
{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:
10/5
No_Parallel_Conflict_Checks

This policy imposes no restrictions on concurrent actions arising from parallel constructs.
11/5
No_Tasking_Conflict_Checks

This policy imposes no restrictions on concurrent actions arising from tasking constructs.
12/5
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:
13/5
the shared object is volatile;
14/5
the two logical threads of control are both known to also refer to a shared synchronized object; and
15/5
each thread whose potentially conflicting action updates the shared volatile object, also updates this shared synchronized object.
15.a/5
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. 
16/5
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:
17/5
the shared object is volatile;
18/5
the two tasks are both known to also refer to a shared synchronized object; and
19/5
each task whose potentially conflicting action updates the shared volatile object, also updates this shared synchronized object.
19.a/5
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. 
20/5
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.
21/5
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.
22/5
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

23/5
{AI12-0344-1} For a subprogram, the following language-defined representation aspect may be specified:
24/5
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.
25/5
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.]
25.a/5
Aspect Description for Parallel_Calls: Specifies whether a given subprogram is expected to be called in parallel.

Implementation Permissions

26/5
{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.
26.a/5
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

26.b/5
{AI12-0267-1} Conflict check policies (and the associated checks) are new.
26.c/5
{AI12-0344-1} Aspect Parallel_Calls is new. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe