Version 1.6 of ai12s/ai12-0064-1.txt

Unformatted version of ai12s/ai12-0064-1.txt version 1.6
Other versions for file ai12s/ai12-0064-1.txt

!standard 9.5.1(18)          14-10-14 AI12-0064-1/03
!class Amendment 13-04-22
!status work item 13-04-22
!status received 13-04-22
!priority Medium
!difficulty Medium
!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 an aspect Nonblocking (or the converse, Potentially_Blocking?)
Add at the end of 9.5.1 (as continuation of bounded error section?)
For a callable entity, a generic subprogram, a package, or a generic package, the following language-defined representation aspect may be specified:
The type of aspect Nonblocking is Boolean. When aspect Nonblocking is True for an 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 or generic package. If not specified for a library package or generic library package, the default is False.
When a callable entity is nonblocking, a call to the entity is considered to be within a protected operation for purposes of the check described above that is associated with invoking an operation that is potentially blocking (including interactions with pragma Detect_Blocking (see H.5)). In addition, a call to an entity that is not a nonblocking entity is considered potentially blocking for the purposes of the check.
AARM Ramification: This implies, if Detect_Blocking is set, that calling a potentially blocking operation from the body of Nonblocking subprogram raises Program_Error. That includes calling any non-nonblocking subprograms.
AARM Implementation Note: We make calling non-nonblocking subprograms from the body of a nonblocking subprogram a bounded error so that the check can be made statically in the case that pragma Detect_Blocking is in force. We certainly do not want distributed overhead in the case where pragma Detect_Blocking is in force, a nonblocking subprogram that is called from outside of a protected action then calls a normal subprogram that uses a potentially blocking operation (this case would require an extra TCB flag or the like to be reliably detected, which is required in the presence of the pragma).
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.
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 consequences.)
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.
"Nonblocking" is shorter than "Potentially_Blocking" but the latter matches the RM terminology better, so might be preferred (with corresponding complementary semantics!).
It will be necessary to sprinkle appropriate annotations throughout the language-defined packages to match the current blocking vs. potentially-blocking categorizations.
!ACATS test
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,

package My_Stuff
    with Global => (In_Out => Synchronized),
         Potentially_Blocking => False
    procedure Do_Something (X : in out T;
                            Y : in U);
    function Query_Something (A : T)
          return Z;
end My_Stuff;

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


Questions? Ask the ACAA Technical Agent