CVS difference for ai12s/ai12-0279-1.txt

Differences between 1.4 and version 1.5
Log of other versions for file ai12s/ai12-0279-1.txt

--- ai12s/ai12-0279-1.txt	2018/09/05 21:28:47	1.4
+++ ai12s/ai12-0279-1.txt	2018/10/17 03:22:48	1.5
@@ -1,4 +1,5 @@
-!standard D.2.4 (10/3)                               18-05-14  AI12-0279-1/01
+!standard D.2.1(1.5/2)                                18-10-14  AI12-0279-1/02
+!standard D.2.1(8/2)
 !class binding interpretation 18-05-14
 !status work item 18-05-14
 !status received 18-05-11
@@ -30,40 +31,62 @@
 
 !recommendation
 
-The solution to this unpredictability is to declare all potentially blocking
-operations to be preemption points. In this case, all calls to an entry or wait
-operations on a suspension point are preemption points regardless of whether
-they are open or not. This simple change would make non-preemptive dispatching
-more predictable.
+The solution to this unpredictability is to define a Boolean Yield aspect that
+may be specified on subprogram declarations. If a call to a subprogram with the
+Yield aspect specified as true has not reached a task dispatching point before
+returning from the call, then a task dispatching point is inserted before the
+return. This simple change would make non-preemptive dispatching more
+predictable, while giving the programmer better control for placing the extra
+task dispatching points. All language defined subprograms that have the
+Non_Blocking aspect as False, except for the IO related calls, will be updated
+to specify Yield as True.
 
 !wording
 
-Modify D.2.4 (10/3)
-For this policy, {invoking an operation that is potentially blocking,}
-[blocking or ]termination of a task, [a delay_statement], {and} a call to
-Yield_To_Higher[, and a call to Yield_To_Same_Or_Higher or Yield] are the only
-task dispatching points (see D.2.1).
-
-Modify D.2.4 (10.a/3)
-{Reason: We want higher predictability for determining the blocking time for
-higher priority tasks. We want starting any potentially blocking operation to be
-a dispatching point, as otherwise calling an open entry or a suspension object
-that is open would not trigger dispatching, but would if the entry or suspection
-object happened to be closed at the time of the call.}
-
-Ramification: {Any potentially blocking operation}[A delay_statement] is always
-a task dispatching point even if it is not blocking. Similarly, a call to
-Yield_To_Higher is never blocking, but it is a task dispatching point{.}
-In each of these cases, they can cause the current task to stop running
-(it is still ready). [Otherwise, the running task continues to run until it is
-blocked.]
+Add after D.2.1 (1.5/2)
 
+For a noninstance subprogram (including a generic formal subprogram),
+a generic subprogram, an entry, or an access-to-subprogram type, the
+following language-defined aspect may be specified with an
+aspect_specification (see 13.1.1):
+
+Yield
+   The type of aspect Yield is Boolean.
+
+   If directly specified, the aspect_definition shall be a static expression.
+   If not specified (including by inheritance), the aspect is False.
+
+   If a Yield aspect is specified True for a primitive subprogram S of a tagged
+   type T, then the aspect is inherited by descendants of T (including the
+   class-wide type T'Class).
+
+   The Yield aspect with value True is nonoverridable. (see 13.1.1)
+
+Add after D.2.1 (8.2)
+
+The Yield aspect specifies that a task dispatching point will be reached
+prior to returning from a call for a callable entity or an
+access-to-subprogram type.
+An implicit call to Yield is issued prior to returning from a call if a
+task dispatching point is not reached at some point during the call by
+the logical thread of control that issued the call.
+
 !discussion
 
-We don't need to say anything about calls such as Yield, Suspend_Until_True,
-or Suspend_Until_True_And_Set_Deadline, as these subprograms all have the
-Nonblocking aspect specified as False, and the new wording covers all
-potentially blocking operations, which includes these calls.
+We considered having potentially blocking operations be task dispatching points,
+but that raised the possibility that low-level subprograms such as IO calls that
+normally do not block could generate excessive overhead if they were to block.
+In contrast, this approach gives better control to the programmer to specify
+where extra task dispatching points should be placed.
+
+We considered specifying the Yield aspect on some of the language-defined
+subprograms such as Ada.Task_Identification.Abort_Task and
+Ada.Synchronous_Task_Control.Suspend_Until_True, but eventually decided that the
+Yield aspect as defined provides sufficient control to the programmer for adding
+extra task dispatching points, and it is expected that the aspect will typically
+be applied higher up in the call tree. Also there were concerns that forcing
+task dispatching points on any of the language defined subprograms could add
+unnecessary overhead where it was not needed.
 
 !ASIS
 
@@ -71,8 +94,8 @@
 
 !ACATS test
 
-An ACATS C-Test is needed to check that a potentially blocking operation is
-a dispatching point, even if it does not block.
+An ACATS C-Test is needed to check that a call with the Yield aspect True
+will generate a task dispatching point, even if it does not block.
 
 !appendix
 
@@ -411,13 +434,13 @@
 Sent: Sunday, May 20, 2018  5:49 PM
 
 The AI says:
-> All potentially blocking operations are preemption points for the 
+> All potentially blocking operations are preemption points for the
 > Non-Preemptive Dispatching Policy
 
 The RM says:
 > The following are defined to be potentially blocking operations:
 >  ... << good stuff>>
->  a call on a subprogram whose body contains a potentially blocking 
+>  a call on a subprogram whose body contains a potentially blocking
 >   operation.
 
 So, the rules combine to make every call site down the stack towards the
@@ -445,14 +468,91 @@
 using the April version of the draft RM (the HTML version, since there is no
 April PDF version) in order to see that.
 
-> So, the rules combine to make every call site down the stack 
+> So, the rules combine to make every call site down the stack
 > towards the really potentially blocking operation a dispatching point.
 
 As noted above, they don't.
- 
+
 > I don't think that anybody wants that to happen.
 
 And it doesn't.
+
+****************************************************************
+
+From: Tullio Vardanega
+Sent: Sunday, October 14, 2018  2:31 PM
+
+At the Lisbon meeting, Brad and I were tasked to refine AI12-0279-1
+along the lines of the discussion we had there. The gist of it was to
+seek ways to obtain the desired effect avoiding unnecessary overhead.
+In the record, this action was attached to Brad's homework.
+Brad and I have come up with the following revision, which we believe
+addresses the intent.
+
+[This was followed by version /02 of the AI - Editor.]
+
+****************************************************************
+
+From: Tullio Vardanega
+Sent: Monday, October 15, 2018 11:57 AM
+
+Apologies for stammering this AI.
+I should have added to the first !wording para that Yield should default to
+False, when the aspect is not specified. Thanks Alan for suggesting.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, October 16, 2018 10:17 PM
+
+I added the following paragraph (stolen from aspect Pack) to the AI wording:
+
+If directly specified, the aspect_definition shall be a static expression. If
+not specified (including by inheritance), the aspect is False.
+
+You didn't mention the first part, but you must be intending that based on the
+rest of the text.
+
+[This was added to version /02 of the AI - Editor.]
+
+----
+
+Some other comments:
+
+>The Yield aspect with value True is nonoverridable. (see 13.1.1)
+
+Aspects are either nonoverridable or they aren't. The value doesn't have
+anything to do with it. Moreover, the term is only for type-related aspects, so
+you're probably not getting whatever you are intending from this rule. And a
+nitpick - the period should be after the ).
+
+Probably this should either be replaced by what you mean. Maybe add it to the
+preceding paragraph:
+   If a Yield aspect is specified True for a primitive subprogram S of a tagged
+   type T, then the aspect is inherited by descendants of T (including the
+   class-wide type T'Class). {If the Yield aspect is specified for a subprogram which
+   inherits the value of the aspect, the specified value shall be confirming.}
+
+---
+
+On this line, you allow specifying Yield for an access-to-subprogram type. I'm
+not sure how that is supposed to work. In general, compiler will have to try to
+add a call to [subprogram] Yield before returning from a Yield => True routine
+unless it can prove that some other blocking operation was (certainly) executed
+by the routine. For a subprogram, that won't add overhead much of the time,
+since the compiler will see the body and will be able to determine that the
+needed overhead has already happened (or that it happens on most paths, adding
+overhead only to specific paths). For an access-to-subprogram, the actual
+subprogram is unknown, so such overhead would have to be added to every call
+unconditionally. I suppose an implementation could use an alternative
+implementation that when the Yield is False on the subprogram for which 'Access
+is taken, a wrapper is generated that has the needed task dispatching point;
+doing nothing otherwise. But that seems just as expensive in normal use (most
+routines won't have the Yield => True).
+
+I guess I would not include access-to-subprogram here; if someone wants to
+ensure that some call on such a value was a task dispatching point, they can add
+a Yield call manually. (I don't see this coming up often!)
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent