CVS difference for ai12s/ai12-0281-1.txt
--- ai12s/ai12-0281-1.txt 2018/06/16 03:03:28 1.3
+++ ai12s/ai12-0281-1.txt 2019/02/27 06:24:07 1.4
@@ -1,10 +1,12 @@
-!standard D.16(7/3) 18-06-05 AI12-0281-1/01
+!standard D.16(7/3) 19-02-26 AI12-0281-1/02
!standard D.16(10/3)
!standard D.16(11/3)
!standard D.16(14/3)
!standard J.5.9(4/3)
!standard J.5.9(6/3)
!class Amendment 18-06-05
+!status Amendment 1-2012 19-02-26
+!status ARG Approved 9-0-2 19-02-26
!status work item 18-06-05
!status received 18-05-19
!priority Low
@@ -18,9 +20,9 @@
!problem
A very desirable property of an Ada program on a single core computer is that
-it can be guaranteed to be deadlock free, with no unbounded priority inversions
+it can be guaranteed to be deadlock-free, with no unbounded priority inversions
when the priority ceiling protocol is applied. Unfortunately, this property
-can not be easily proven for multi-tasking Ada programs executing on a multicore
+cannot be easily proven for multitasking Ada programs executing on a multicore
processor. This is because a lock must be obtained prior to executing a protected
action. For instance, consider two protected objects that have protected
procedures that in turn call a protected procedure of the other object. If task
@@ -28,7 +30,7 @@
task B calls protected object P2, which calls a protected procedure of P1,
deadlock is a possibility, since both tasks will have acquired locks to one of
the protected objects, while waiting endlessly for the lock of the other
-protected object. If the protected objects were implemented with lock free
+protected object. If the protected objects were implemented with lock-free
algorithms, or if it could be guaranteed that all tasks that interact with a
protected object execute on the same processor, then this deadlocking could be
avoided. Should Ada provide better mechanisms to guarantee that deadlocking will not
@@ -38,12 +40,12 @@
!proposal
The goal of this proposal is to allow the CPU aspect to be specified on a
-declaration of a protected type or a stand alone protected object. This ensures
+declaration of a protected type or a stand-alone protected object. This ensures
that all tasks that invoke protected actions of such a protected object are executing
on the same CPU, which implies that the runtime can be simpler without needing
locks to be acquired, thus avoiding deadlock.
-Program_Error would be raised if a task executing on a CPU other than the one
+Program_Error would be raised if a task assigned to a CPU other than the one
specified for the protected object attempts to execute a protected action of that
protected object.
@@ -57,13 +59,13 @@
Modify D.16 (8.a/3)
Aspect Description for CPU: Processor on which a given task{, or calling task
-for a protected type} should run.
+for a protected operation} should run.
Modify D.16 (10/3)
-The CPU aspect shall not be specified on [a] task { or protected }interface type{s}.
+The CPU aspect shall not be specified on a task { or protected }interface type.
Modify D.16 (11/4)
-The expression specified for the CPU aspect of [a] task { or protected }type{s} is
+The expression specified for the CPU aspect of a task { or protected }type is
evaluated each time an object of the [task]{corresponding} type is created
(see 9.1 {and 9.4}). The CPU value is then associated with the [task] object.
@@ -107,14 +109,10 @@
single_protected_declaration that contains the pragma. Otherwise}[; otherwise],
the expression is associated with the aspect for the subprogram that contains the pragma.
-Modify K.1 (15/3)
-CPU Processor on which a given task {, or calling task
-for a protected type} should run. See D.16.
-
!discussion
-From a real-time perspective, very efficient lock free data structures can in
-theory be obtained in a straight forward manner when the Ravenscar Profile is
+From a real-time perspective, very efficient lock-free data structures can in
+theory be obtained in a straightforward manner when the Ravenscar Profile is
being applied, and when it is known that all use of a protected object is by
tasks that execute on the same processor. This is because each task is locked
to execute on a specific CPU, and because the ceiling priority protocol is in
@@ -128,15 +126,112 @@
declaration, which could be applied to protected procedures, or protected
functions, but not protected entries.
-It would be helpful if the CPU aspect could be applied to a protected type
-declaration, or single protected object, which would imply that all calls to the
-protected object are via tasks that are executing on the same CPU.
+When the CPU aspect is applied to a protected type declaration, or single
+protected object, it is implied that all calls to the protected object are via
+tasks that are assigned to (and thus executing on) the same CPU.
-With such a specification in place, this would provide an indication to the
+With such a specification in place, this provides an indication to the
implementation that locking is not needed, and that any overhead associated with
-locking, including space for the lock in memory and initialisation and
-finalisation of the locks can be eliminated.
+locking, including space for the lock in memory and initialization and
+finalization of the locks can be eliminated.
+
+
+!corrigendum D.16(7/3)
+
+@drepl
+For a task type (including the anonymous type of a @fa<single_task_declaration>) or
+subprogram, the following language-defined representation aspect may be specified:
+@dby
+For a task type (including the anonymous type of a @fa<single_task_declaration>),
+protected type (including the anonymous type of a @fa<single_protected_declaration>),
+or subprogram, the following language-defined representation aspect may be specified:
+
+!corrigendum D.16(10/3)
+
+@drepl
+The CPU aspect shall not be specified on a task interface type.
+@dby
+The CPU aspect shall not be specified on a task or protected interface type.
+
+!corrigendum D.16(11/4)
+
+@drepl
+The @fa<expression> specified for the CPU aspect of a task type is evaluated each
+time an object of the task type is created (see 9.1). The CPU value is then
+associated with the task object.
+@dby
+The @fa<expression> specified for the CPU aspect of a task or protected type
+is evaluated each time an object of the corresponding type is created (see
+9.1 and 9.4). The CPU value is then associated with the object.
+
+!corrigendum D.16(14/3)
+
+@drepl
+The CPU value determines the processor on which the task will
+activate and execute; the task is said to be assigned to
+that processor. If the CPU value is Not_A_Specific_CPU,
+then the task is not assigned to a processor.
+A task without a CPU aspect specified will activate and execute on the same
+processor as its activating task if the activating task is assigned
+a processor. If the CPU value is not in the range of
+System.Multiprocessors.CPU_Range or is greater than Number_Of_CPUs
+the task is defined to have failed, and it becomes a completed task (see
+9.2).
+@dby
+For a task, the CPU value determines the processor on which the task will
+activate and execute; the task is said to be assigned to
+that processor. If the CPU value is Not_A_Specific_CPU,
+then the task is not assigned to a processor.
+A task without a CPU aspect specified will activate and execute on the same
+processor as its activating task if the activating task is assigned
+a processor. If the CPU value is not in the range of
+System.Multiprocessors.CPU_Range or is greater than Number_Of_CPUs
+the task is defined to have failed, and it becomes a completed task (see
+9.2).
+
+For a protected type, the CPU value determines the processor on which calling tasks
+will execute; the protected object is said to be assigned to that processor. If
+the CPU value is Not_A_Specific_CPU, then the protected object is not assigned to
+a processor. A call to a protected object that is assigned to a processor from a
+task that is not assigned a processor or is assigned a different processor
+raises Program_Error.
+
+@s8<@i<Implementation Advice>>
+
+Starting a protected action on a protected object assigned to a processor should
+be implemented without busy-waiting.
+
+!corrigendum J.15.9(4/3)
+
+@drepl
+A CPU pragma is allowed only immediately within a @fa<task_definition>, or the
+@fa<declarative_part> of a @fa<subprogram_body>.
+@dby
+A CPU pragma is allowed only immediately within a @fa<task_definition>,
+@fa<protected_definition>, or the @fa<declarative_part> of a
+@fa<subprogram_body>.
+
+!corrigendum J.15.9(6/3)
+
+@drepl
+For an implementation that supports Annex D, a @fa<pragma> CPU specifies the value of
+the CPU aspect (see D.16). If the @fa<pragma> appears in a @fa<task_definition>, the
+@fa<expression> is associated with the aspect for the task type or
+@fa<single_task_declaration> that contains the @fa<pragma>; otherwise, the
+@fa<expression> is associated with the aspect for the subprogram that contains
+the @fa<pragma>.
+@dby
+For an implementation that supports Annex D, a @fa<pragma> CPU specifies the value of
+the CPU aspect (see D.16). If the @fa<pragma> appears in a @fa<task_definition>, the
+@fa<expression> is associated with the aspect for the task type or
+@fa<single_task_declaration> that contains the @fa<pragma>. If the pragma appears in
+a @fa<protected_definition>, the @fa<expression> is associated with the aspect
+for the protected type or @fa<single_protected_declaration> that contains the
+@fa<pragma>. Otherwise, the
+@fa<expression> is associated with the aspect for the subprogram that contains
+the @fa<pragma>.
+
!ASIS
TBD.
@@ -242,6 +337,39 @@
“Modify D.16 (8.a/3)
Aspect Description for CPU: Processor on which a given task{, or calling task
for a protected type} should run.”
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February 26, 2018 11:46 PM
+
+When we discussed this AI today, we mentioned that (in general) aspect CPU is
+not static, so the compiler cannot always know whether or not busy-waiting is
+needed. We didn't think this is a problem, since aspect CPU is usually static,
+and is always static for profiles Ravenscar/Yorvik.
+
+The Implementation Advice in this AI reads:
+
+ Starting a protected action on a protected object assigned to a processor
+ should be implemented without busy-waiting.
+
+This is not possible in general, as noted above. Should we fix this wording so
+it applies only to cases where the implementation could reasonably do the
+right thing? A strategic insertion of "statically" should do the trick:
+
+ Starting a protected action on a protected object statically assigned to
+ a processor should be implemented without busy-waiting.
+
+Generally, we try to avoid asking the impossible in implementation advice, and
+while I suppose it could be accomplished with heroic efforts (generating all
+of the operations both ways, and picking one at runtime), that would seem to
+defeat the goal of analysis (especially at the generated code level) and
+surely efficiency.
+
+That seems especially true in this case, where the advice is as much a
+statement to users of what they ought to expect as it is to implementers.
+
+Thoughts?
****************************************************************
Questions? Ask the ACAA Technical Agent