Version 1.7 of ai12s/ai12-0064-1.txt
!standard 9.5.1(18) 15-06-17 AI12-0064-1/04
!class Amendment 13-04-22
!status work item 13-04-22
!status received 13-04-22
!subject Nonblocking subprograms
Aspect Nonblocking is added.
During a protected action, it is a bounded error to invoke an operation that
is potentially blocking. There is currently no mechanism (other than a
comment) to specify that a given subprogram is intended to be safely callable
during a protected action (i.e., that the subprogram will not invoke an
operation that is potentially blocking). This seems like a useful part of a
subprogram's "contract" that should be (optionally) specifiable at the point
of a subprogram's declaration.
Add at the end of 9.5.1 (as continuation of bounded error section?)
For a callable entity, a generic subprogram, a package, a generic
package, or a protected unit, the following language-defined
representation aspect may be specified:
The type of aspect Nonblocking is Boolean. When aspect Nonblocking
is False for a callable entity, the entity might contain a
potentially blocking operation. If the aspect is True for a
callable entity, the entity is said to be nonblocking. If
directly specified, the aspect_definition shall be a static
expression. This aspect is inherited by overridings of dispatching
subprograms; if not specified, the aspect is determined by the
setting for the innermost package, generic package, or protected
unit. If not specified for a library package or generic library
package, the default is False.
A nonblocking callable entity shall not contain a call on a
callable entity for which the Nonblocking aspect is False, nor
shall it contain any of the following:
* a select_statement;
* an accept_statement;
* an entry_call_statement;
* a delay_statement;
* an abort_statement;
* task creation or activation.
A subprogram shall be nonblocking if it overrides a dispatching
nonblocking procedure. In addition to the places where Legality
Rules normally apply (see 12.3), this rule applies also in the
private part of an instance of a generic unit.
AARM Ramification: specifying Nonblocking is False imposes
no requirements. Specifying Nonblocking is True imposes
additional compile-time checks to prevent blocking, but does not
prevent deadlock. pragma Detect_Blocking can be used to ensure
that Program_Error is raised in a deadlock situation.
We considered changing from aspect Nonblocking to Potentially_Blocking, as that
matches RM terminology better, but we ultimately concluded that would be a
mistake. Furthermore, "nonblocking" is used in 9.5.1, albeit somewhat
informally. Were we to switch to Potentially_Blocking, the default would be
True rather than False, which is unlike other Boolean aspects. Furthermore, with
Potentially_Blocking => True, we wouldn't require that it be potentially
blocking, merely allow it. Perhaps Allow_Blocking would be better, but that
doesn't match RM terminology at all, and still has the "wrong" default.
We've modeled this aspect after No_Return, which has a similar purpose
and presumably has already worked out the needed rules.
For this reason, we don't have nonblocking access-to-subprogram types.
One could imagine such a thing, but it would take a number of additional
rules and certainly wouldn't be "keeping it simple".
The rules do not allow calling "normal" subprograms from a nonblocking
subprogram. This allows detecting any potentially blocking operations used
in a nonblocking subprogram statically. This is important if pragma
Detect_Blocking is used, as such detection is required. (Otherwise, this
is just a bounded error and the "mistake" can be ignored with the usual
We have provided package-level defaults, given that many packages will
have all of their subprograms non-blocking. We might want to make the
default for a Pure package to be nonblocking, as that is almost always
the case, since blocking typically implies the use of some kind of
global lock. However, that would create incompatibilities, so we leave
it to the programmer to specify Nonblocking if desired on a Pure package.
Similarly we might specify that protected subprograms are by default
Nonblocking=>True. However that would be incompatible, as they could not call
subprograms with a default Nonblocking aspect value of False. It might be
possible to specify Nonblocking=>True as the default for protected subprograms
in a future version of the standard (and clearly an implementation could at
least provide a warning when a call is made to a subprogram with Nonblocking of
False). We allow specifying Nonblocking on a protected unit to provide a
default for all of the enclosed protected subprograms.
It will be necessary to sprinkle appropriate annotations throughout the
language-defined packages to match the current blocking vs.
ACATS B-Tests and C-Tests.
From: Tucker Taft
Sent: Monday, October 6, 2014 10:35 AM
Another section of the HILT paper related to a Potentially_Blocking aspect.
Below is that section. As Randy and others have pointed out, we would need to
put a specification of the Potentially_Blocking aspect on each of the existing
Ada standard library packages, since the default implies blocking.
Another important piece of knowledge the caller of a subprogram might need to
know is whether or not the call is potentially blocking. The Ada language
defines potentially blocking operations to include select statements, accept
statements, delay statements, abort statements, and task creation or activation,
among others. When executing parallel code, potentially blocking operations can
cause problems such as deadlocks. Currently there is no standard way in Ada to
specify that a subprogram is potentially blocking. If the compiler cannot
statically determine that a subprogram call is potentially blocking, the
programmer has to rely on run-time checking to detect these sorts of problems.
We propose the addition of a boolean Potentially_Blocking aspect that can be
applied to subprogram specifications to indicate whether they use constructs
that are potentially blocking or call other subprograms that have the
Potentially_Blocking aspect with a value of True. Such an aspect enhances he
safety of parallel calls, and also generally improves the safety of Ada, since
it allows the compiler to statically detect more problems involving calls on
potentially blocking subprograms. The default value for the Potentially_Blocking
aspect is True.
We also propose that these defaults can be overridden for a package by allowing
these aspects to be specified at package level, with the meaning that they
establish a default for all subprograms in the package. For example,
with Global => (In_Out => Synchronized),
Potentially_Blocking => False
procedure Do_Something (X : in out T;
Y : in U);
function Query_Something (A : T)
Indicates that all subprograms in package My_Stuff involve access to
synchronized globals, and all of these calls are not potentially blocking calls
(in particular these cannot include entry calls, delays, select statements, etc.
[23, section 9.5.1]). Such an annotation would alleviate the need to repeat the
Global or Potentially_Blocking aspect on each subprogram, as long as the
package-level default is appropriate for that subprogram.
In the absence of such an explicit package-wide default, the default for
Potentially_Blocking would be True, and the default for Global would be (In_Out
=> all) in a normal package, and null in a declared-pure package.
From: Tucker Taft
Sent: Tuesday, October 14, 2014 12:04 PM
Here is a very modest update to AI-0064 on the Nonblocking aspect (or
Potentially_Blocking if you prefer). I hadn't realized it was on my list of
homework until today...
[Editor's note: This is version /03 of the AI.]
From: Tucker Taft
Sent: Wednesday, June 17, 2015 6:46 AM
After going back and forth a couple of times, I settled on Nonblocking rather
than Potentially_Blocking for the name of the aspect. See the !discussion for
an explanation. [This is version /04 of the AI - Editor.]
From: Randy Brukardt
Sent: Thursday, June 18, 2015 12:10 AM
Mostly looks good. A couple of comments:
> Add an aspect Nonblocking
> Add at the end of 9.5.1 (as continuation of bounded error section?)
> For a callable entity, a generic subprogram, a package, a generic
> package, or a protected unit, the following language-defined
> representation aspect may be specified:
> The type of aspect Nonblocking is Boolean. When aspect Nonblocking
Something wrong here, as there is no aspect name given. Based on the rest of the
text, "Nonblocking" needs to be inserted under the colon. I'll fix this in the
There doesn't seem to be an optional way to specify nonblocking for a formal
subprogram. I think that will be necessary if we want to require nonblocking on
container operations (for instance, in a future parallel container).
In particular, if we have an ordered map:
type Key_Type is private;
type Element_Type is private;
with function "<" (Left, Right : Key_Type) return Boolean is <>;
with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Nonblocking_Ordered_Maps is
function Find (Container : Map; Key : Key_Type) return Cursor
The calls to "<" in Find would be illegal, as the function doesn't have
Nonblocking = True. One could imagine somehow deferring this check until the
instantiation, but of course Legality Rules aren't enforced in the body of an
instance. And I'm sure we don't want a runtime check here.
If one put the Nonblocking on the package as a whole, then the problem becomes
that we don't have any rule that would prevent instantiation with a function "<"
that isn't nonblocking. Again, the Legality Rule that would fail is in the body
of the generic, so it isn't rechecked (in that case, the body of Find would
compile successfully, but the promise would be violated).
What we want, I think, is two things: (1) the ability to specify the aspect on
the formal subprogram (its weird to only allow inheriting it, and if you wanted
two subprograms to have different setting you'd be out of luck); and (2)
matching rules for actuals of formal subprograms when Nonblocking = True (either
explicitly, or inherited from an outer package). [Specifically, it's an error if
the actual function has Nonblocking = False when the formal subprogram has
Nonblocking = True. Otherwise, it's OK.]
We don't have any aspects that can be specified on generic formals today, but
we've always planned that some would appear eventually. The main thing that each
one needs is a matching rule; this one seems simple.
No_Return doesn't have any such thing, because it doesn't really come up for
that. So I'm not surprised that it is missing.
(I'm dubious about not having a mechanism for access-to-subprogram as well, but
since I don't have a use case for that, I won't push there.)
Questions? Ask the ACAA Technical Agent