Version 1.2 of ai12s/ai12-0279-1.txt

Unformatted version of ai12s/ai12-0279-1.txt version 1.2
Other versions for file ai12s/ai12-0279-1.txt

!standard D.2.4 (10/3)          18-05-14 AI12-0279-1/01
!class binding interpretation
!class binding interpretation 18-05-14
!status work item 18-05-14
!status received 18-05-11
!priority Medium
!difficulty Easy
!qualifier Omission
!subject Nonpreemptive Dispatching Needs More Dispatching Points
!summary
All potentially blocking operations are preemption points for the Non-Preemptive Dispatching Policy.
!question
In non-preemptive dispatching it is necessary to have controlled points in the code where preemption is enabled, as a mechanism to keep the non-preemptive sections short and reduce blocking time for higher priority tasks. Unlike the preemptive case, these preemption points need to be under the programmer's control in order for the program semantics to be fully predictable. The current wording in the standard mentions "blocking of a task" as a preemption point. This can happen for instance when calling a closed entry or suspension object. However, if the entry is open or the suspension object is true, there is no preemption point, which introduces uncertainty on whether a preemption point is reached and makes it difficult to determine the blocking (non-preemptive) time for higher priority tasks.
Should this nondeterminism be eliminated? (Yes.)
!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.
!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.]
!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.
!ASIS
No ASIS effect.
!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.
!appendix

From: Tullio Vardanega
Sent: Friday, May 11, 2018  2:37 AM

The (short but intense) burst of AIs from the IRTAW group shows evidence that
they (me included) recently had a productive meeting :) In addition to Alan
Burns' AI with the revised wording of the Deadline Floor Protocol, and Brad
Moore's cut at lock-free atomic operations, I was tasked to submit another --
very simple indeed -- AI with a binding interpretation of the semantics of
non-blocking dispatching, which I attach below.

[This attached version /01 of this AI - Editor.]

****************************************************************

From: Tullio Vardanega
Sent: Friday, May 11, 2018  2:43 AM

Ehm.
Thanks to the echoing service, I was that what I wrote in premise to the AI I
have just sent reads rather weird.
The subject matter is the semantics of potentially blocking operations in
nonpreemptive dispatching.
Apologies for botching up the wording ...

****************************************************************

From: Brad Moore
Sent: Friday, May 11, 2018  6:54 PM

I thought of something today, unfortunately after Tullio had sent the AI to
the ARG.

We should probably add a couple paragraphs in the Discussion section stating
that we considered defining the rules to target more precisely the preemption
points (for example making a call on an open entry, or suspension object, or
making calls to Yield, etc) rather than the blanket rule of invoking any
potentially blocking operation.

I think the justification is that the rules are simpler, easier to maintain
and implement, and provides more preemption points that might be useful for
analysis including more likely to break up long bouts of processing, which
was part of the original motivation.

The second paragraph should say something about the case where applications
have not applied the nonblocking aspect to the various subprogram
specifications in the application. An example of this would be legacy systems.
The default is that most such calls have nonblocking=>false, which means they
are potentially blocking. There could be an extremely large number of
preemption points in such an application, which might potentially be
prohibitively expensive. Is this a problem?

This also raises a similar question in my mind, relating to the Nonblocking
aspect. Consider a legacy system where a PO calls subprograms in some non-pure
package. If these are now considered to be potentially blocking due to lack of
a Nonblocking aspect on the specification of the subprogram, the compiler
would start to flag these as errors. Is this a backwards compatibility
problem?

One might be able to apply a configuration pragma to say that the Program_Unit
is by default NonBlocking, but then presumably the compiler might start
flagging routines that actually are potentially blocking as having an
incompatible default, requiring code changes to fix.

The description of Nonblocking aspect in RM 9.5 doesn't mention any backwards
incompatibility. Am I missing something here?

****************************************************************

From: Randy Brukardt
Sent: Monday, May 14, 2018  10:26 PM

> I thought of something today, unfortunately after Tullio had sent the
> AI to the ARG.
>
> We should probably add a couple paragraphs in the Discussion section
> stating that we considered defining the rules to target more precisely
> the preemption points (for example making a call on an open entry, or
> suspension object, or making calls to Yield,
> etc) rather than the blanket rule of invoking any potentially blocking
> operation.
>
> I think the justification is that the rules are simpler, easier to
> maintain and implement, and provides more preemption points that might
> be useful for analysis including more likely to break up long bouts of
> processing, which was part of the original motivation.

You probably should have just proposed some wording to add to the AI; that
would have been quicker than outlining it and hoping that someone else
writes it. I can add it if you write it (and it does seem like it would
clarify the AI).

> The second paragraph should say something about the case where
> applications have not applied the nonblocking aspect to the various
> subprogram specifications in the application. An example of this would
> be legacy systems. The default is that most such calls have
> nonblocking=>false, which means they are potentially blocking. There
> could be an extremely large number of preemption points in such an
> application, which might potentially be prohibitively expensive. Is
> this a problem?

You're confused. "Potentially blocking" is purely a dynamic concept that
hasn't been changed much from Ada 95's version. (The only change is to avoid
a requirement to make a check on every routine *except* those with
Nonblocking.)

"Nonblocking" is a purely static concept. Only language-defined subprograms
that are not Nonblocking are "potentially blocking", and that's the same set
of subprograms as in the past (except for a couple of bugs that got identified
and fixed during that process). It has *no* effect on user-defined subprograms
vis-a-vis Detect_Blocking or the bounded error.

The Bounded Error for potentially blocking can be detected early, if the
subprogram itself is potentially blocking. This is a bug in Ada 95 (a useless
permission that causes problems with other rules, specifically
Detect_Blocking), but given the recent rule changes, such a subprogram is not
itself potentially blocking. I'm pretty sure you would not want to give
permission to do context switches on arbitrary calls. In any case, this is an
Ada 95 issue that we *fixed* recently, not something introduced. Without the
fixes, you would have been right; Ada 95/2005 potentially blocking would not
have been appropriate for defining dispatching points, since it applied to
virtually every subprogram and it is very difficult to tell which routines it
did or didn't apply to.

> This also raises a similar question in my mind, relating to the
> Nonblocking aspect. Consider a legacy system where a PO calls
> subprograms in some non-pure package. If these are now considered to
> be potentially blocking due to lack of a Nonblocking aspect on the
> specification of the subprogram, the compiler would start to flag
> these as errors. Is this a backwards compatibility problem?

This does not happen. All language-defined subprograms are specified one way
or the other (to match the previous definitions), and other routines are never
potentially blocking for this reason.

> One might be able to apply a configuration pragma to say that the
> Program_Unit is by default NonBlocking, but then presumably the
> compiler might start flagging routines that actually are potentially
> blocking as having an incompatible default, requiring code changes to
> fix.
>
> The description of Nonblocking aspect in RM 9.5 doesn't mention any
> backwards incompatibility.
> Am I missing something here?

Yes, read 9.5(56/5) and the associated AARM note carefully. :-) You're
imagining a problem that does not exist.

****************************************************************

From: Randy Brukardt
Sent: Monday, May 14, 2018  10:57 PM

>!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.

For the record, this brings this policy much closer to how Janus/Ada handles
Ada tasking. Janus/Ada reschedules on any call to the task supervisor that can
cause a task to be suspended, whether or not it actually suspends. (This
happened more for practicality than any plan -- since the task supervisor has
its own separate context a switch is needed to execute it, and then selecting
the next task to run on the way out handles all cases the same way [blocking,
delay expiration, etc.]).

Janus/Ada does not however, preempt on any call to a potentially blocking
subprogram (with the exception of the Yield ones, which are mapped to
supervisor calls) -- doing that on I/O would be rather expensive, especially
in the character-at-a-time case. I wonder if this would be better if you
didn't require preemption at most language-defined subprograms that are
potentially blocking - specifically the large number of I/O routines that are
blocking. Most of those might have some internal locking, but often let the
OS do that if necessary. (That is the main reason I haven't implemented
Detect_Blocking; I don't know of any way to do that that doesn't make I/O much
more expensive in non-tasking cases.)

****************************************************************

From: Randy Brukardt
Sent: Monday, May 14, 2018  11:28 PM

> The (short but intense) burst of AIs from the IRTAW group shows
> evidence that they (me included) recently had a productive meeting :)
> In addition to Alan Burns' AI with the revised wording of the Deadline
> Floor Protocol, and Brad Moore's cut at lock-free atomic operations, I
> was tasked to submit another -- very simple indeed -- AI with a
> binding interpretation of the semantics of non-blocking dispatching,
> which I attach below.

You formatted it like an Amendment, but classified it as a Binding
Interpretation, which has !question and !recommendation sections, not !problem
and !proposal. I've fixed this up, taking the second paragraph of the !problem
as the recommendation and adding a question (no question mark and some
reviewers get upset).

****************************************************************

From: Tullio Vardanega
Sent: Monday, May 14, 2018  11:56 PM

Thanks, Randy.

****************************************************************

From: Tullio Vardanega
Sent: Tuesday, May 15, 2018  11:41 AM

I am with Randy in the regard of Brad's concern below.
What this binding-interpretation AI wants to address are solely the
language-defined subprograms that are not Nonblocking. I do not think this
requires additional text, other than perhaps recalling this one-liner (that
Randy may want to nail into legal speak):

!summary
All potentially blocking operations (that is, all the language-defined
subprograms that are not Nonblocking) are preemption points for the
Non-Preemptive Dispatching Policy

****************************************************************

From: Tullio Vardanega
Sent: Tuesday, May 15, 2018  11:49 AM

> For the record, this brings this policy much closer to how Janus/Ada handles
> Ada tasking. ...

Interesting ...
The case of I/O was outside of our (the IRTAW's) thinking, as it would be too
fine a granularity, counter productive for the intent of making the program more
analysable (In addition to costing a lot).

****************************************************************

From: Tucker Taft
Sent: Tuesday, May 15, 2018  12:00 PM

> I am with Randy in the regard of Brad's concern below.
> What this binding-interpretation AI wants to address are solely the
> language-defined subprograms that are not Nonblocking. I do not think this
> requires additional text, other than perhaps recalling this one-liner (that
> Randy may want to nail into legal speak):

I don't quite follow.  Randy was recommending we do *not* make most
potentially-blocking language-defined subprograms into preemption points.
Rather, I think he we suggesting we identify the particular language-defined
subprograms that *must* be preemption points, and I suppose *allow* other
potentially-blocking subprograms to be preemption points, rather than require
them to be.

****************************************************************

From: Tullio Vardanega
Sent: Tuesday, May 15, 2018  12:44 PM

If there was a place in the RM (other than the index) that itemized all such
subprograms, we might have thought of ticking off explicitly those that mattered
to our intent.

The (silent) boundary of our concern was chapter 9.
The RM index of terms, under "blocking, potential" also has:
- C.7.1(16), which we would not want to use for the AI purpose, but should
  certainly be a dispatching point for the nonpreemptive policy
- E.4(17) and E.5(23), which should be.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, May 15, 2018  2:14 PM

> ... Rather, I think he we suggesting we identify the particular
> language-defined subprograms that
> *must* be preemption points, and I suppose *allow* other
> potentially-blocking subprograms to be preemption points, rather than
> require them to be.

Since the purpose of the AI is to get *more* determinism, I doubt that having
some preemption points being optional helps that goal.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, May 15, 2018   2:38 PM

> If there was a place in the RM (other than the index) that itemized
> all such subprograms, we might have thought of ticking off explicitly
> those that mattered to our intent.

There is no such place, intentionally (there never has been, either).

> The (silent) boundary of our concern was chapter 9.
> The RM index of terms, under "blocking, potential" also has:
> - C.7.1(16), which we would not want to use for the AI purpose, but
> should certainly be a dispatching point for the nonpreemptive policy
> - E.4(17) and E.5(23), which should be.

Any such index entries that remains on subprogram are in deleted text and only
show in the AARM. So pay no attention to that! All of the English wording making
subprograms potentially blocking has been removed (or should have been removed -
if you find any outside of 9.5, tell me), along with any such index entries. The
index entries were never were consistently added in the first place.

You can find a complete list in the !discussion of AI12-0241-1 -- any nongeneric
unit with Nonblocking => False is potentially blocking. (Generic units aren't
potentially blocking, because it is the instance that actually defines the
subprograms, and that is user-defined. This includes all of the containers.
Also, packages like finalization only define abstract types/routines; the
user-defined routines that override those are the ones that do the work and
they're not potentially blocking since they're user-defined.)

Taking a quick look at that list, I would suggest simply excepting all of the
I/O routines from being a preemption point in this way (that's by far the
majority of them) -- they still could preempt if they actually execute a
potentially blocking operation, but they themselves do not do so.

****************************************************************

From: Tucker Taft
Sent: Tuesday, May 15, 2018  3:41 PM

> Since the purpose of the AI is to get *more* determinism, I doubt that
> having some preemption points being optional helps that goal.

I would think having more preemption points is OK, but I defer to the RT
experts.

****************************************************************


Questions? Ask the ACAA Technical Agent