Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
 
Annotated Ada Reference Manual (Ada 202x Draft 25)Legal Information
Contents   Index   References   Search   Previous   Next 

9.5 Intertask Communication

1
The primary means for intertask communication is provided by calls on entries and protected subprograms. Calls on protected subprograms allow coordinated access to shared data objects. Entry calls allow for blocking the caller until a given condition is satisfied (namely, that the corresponding entry is open — see 9.5.3), and then communicating data or control information directly with another task or indirectly via a shared protected object.

Static Semantics

2/3
{AI05-0225-1} {AI05-0291-1} When a name or prefix denotes an entry, protected subprogram, or a prefixed view of a primitive subprogram of a limited interface whose first parameter is a controlling parameter, the name or prefix determines a target object, as follows: 
2.a/3
To be honest: {AI05-0291-1} This wording uses "denotes" to mean "denotes a view of an entity" (when the term is used in Legality Rules), and "denotes an entity" (when the term is used in Dynamic Semantics rules). It does not mean "view of a declaration", as that would not include renames (a renames is not an entry or protected subprogram). 
3/3
{AI05-0291-1} If it is a direct_name or expanded name that denotes the declaration (or body) of the operation, then the target object is implicitly specified to be the current instance of the task or protected unit immediately enclosing the operation; a call using such a name is defined to be an internal call;
4/3
{AI05-0291-1} If it is a selected_component that is not an expanded name, then the target object is explicitly specified to be the object denoted by the prefix of the name; a call using such a name is defined to be an external call
4.a
Discussion: For example: 
4.b
protected type Pt is
  procedure Op1;
  procedure Op2;
end Pt;
4.c
PO : Pt;
Other_Object : Some_Other_Protected_Type;
4.d
protected body Pt is
  procedure Op1 is begin ... end Op1;
4.e
  procedure Op2 is
  begin
    Op1; -- An internal call.
    Pt.Op1; -- Another internal call.
    PO.Op1; -- An external call. It the current instance is PO, then
            -- this is a bounded error (see 9.5.1).
    Other_Object.Some_Op; -- An external call.
  end Op2;
end Pt;
5/3
{AI05-0291-1} If the name or prefix is a dereference (implicit or explicit) of an access-to-protected-subprogram value, then the target object is determined by the prefix of the Access attribute_reference that produced the access value originally; a call using such a name is defined to be an external call;
6
If the name or prefix denotes a subprogram_renaming_declaration, then the target object is as determined by the name of the renamed entity.
6.1/3
 {AI05-0291-1} A call on an entry or a protected subprogram either uses a name or prefix that determines a target object implicitly, as above, or is a call on (a non-prefixed view of) a primitive subprogram of a limited interface whose first parameter is a controlling parameter, in which case the target object is identified explicitly by the first parameter. This latter case is an external call.
7
A corresponding definition of target object applies to a requeue_statement (see 9.5.4), with a corresponding distinction between an internal requeue and an external requeue.

Legality Rules

7.1/3
 {AI95-00345-01} {AI05-0225-1} {AI05-0291-1} If a name or prefix determines a target object, and the name denotes a protected entry or procedure, then the target object shall be a variable, unless the prefix is for an attribute_reference to the Count attribute (see 9.9). 
7.a/3
Reason: {AI05-0225-1} The point is to prevent any calls to such a name whose target object is a constant view of a protected object, directly, or via an access value, renames, or generic formal subprogram. It is, however, legal to say P'Count in a protected function body, even though the protected object is a constant view there. 
7.b/3
Ramification: {AI05-0291-1} This rule does not apply to calls that are not to a prefixed view. Specifically a "normal" call to a primitive operation of a limited interface is not covered by this rule. In that case, the normal parameter passing mode checks will prevent passing a constant protected object to an operation implemented by a protected entry or procedure as the mode is required to be in out or out
7.2/5
 {AI12-0166-1} An internal call on a protected function shall not occur within a precondition expression (see 6.1.1) of a protected operation nor within a default_expression of a parameter_specification of a protected operation.
7.c/5
Reason: {AI125-0166-1} These calls will be made before the start of the protected action, and thus would not be subject to the expected mutual exclusion. As such, they would be an automatic race condition (the state of the called object could change before the start of the protected action for the call on the protected entry or subprogram). 
7.d/5
To be honest: {AI125-0166-1} 6.1.1 actually defines "specific precondition expression" and "class-wide precondition expression". This rule is intended to apply to both. 

Dynamic Semantics

8
Within the body of a protected operation, the current instance (see 8.6) of the immediately enclosing protected unit is determined by the target object specified (implicitly or explicitly) in the call (or requeue) on the protected operation. 
8.a
To be honest: The current instance is defined in the same way within the body of a subprogram declared immediately within a protected_body.
9
Any call on a protected procedure or entry of a target protected object is defined to be an update to the object, as is a requeue on such an entry. 
9.a
Reason: Read/write access to the components of a protected object is granted while inside the body of a protected procedure or entry. Also, any protected entry call can change the value of the Count attribute, which represents an update. Any protected procedure call can result in servicing the entries, which again might change the value of a Count attribute. 

Syntax

10/3
{AI05-0030-2} {AI05-0215-1} synchronization_kind ::= By_Entry | By_Protected_Procedure | Optional

Static Semantics

11/3
{AI05-0215-1} For the declaration of a primitive procedure of a synchronized tagged type the following language-defined representation aspect may be specified with an aspect_specification (see 13.1.1):
12/3
Synchronization

If specified, the aspect definition shall be a synchronization_kind.
12.a/3
Aspect Description for Synchronization: Defines whether a given primitive operation of a synchronized interface must be implemented by an entry or protected procedure.
13/3
{AI05-0030-2} {AI05-0215-1} Inherited subprograms inherit the Synchronization aspect, if any, from the corresponding subprogram of the parent or progenitor type. If an overriding operation does not have a directly specified Synchronization aspect then the Synchronization aspect of the inherited operation is inherited by the overriding operation. 

Legality Rules

14/3
{AI05-0030-2} {AI05-0215-1} The synchronization_kind By_Protected_Procedure shall not be applied to a primitive procedure of a task interface.
15/3
{AI05-0030-2} {AI05-0215-1} A procedure for which the specified synchronization_kind is By_Entry shall be implemented by an entry. A procedure for which the specified synchronization_kind is By_Protected_Procedure shall be implemented by a protected procedure. A procedure for which the specified synchronization_kind is Optional may be implemented by an entry or by a procedure (including a protected procedure).
16/3
{AI05-0030-2} {AI05-0215-1} If a primitive procedure overrides an inherited operation for which the Synchronization aspect has been specified to be By_Entry or By_Protected_Procedure, then any specification of the aspect Synchronization applied to the overriding operation shall have the same synchronization_kind.
17/3
{AI05-0030-2} In addition to the places where Legality Rules normally apply (see 12.3), these rules also apply in the private part of an instance of a generic unit. 

Static Semantics

18/5
{AI12-0064-2} An expression is nonblocking-static if it is one of the following:
19/5
a static expression;
20/5
a Nonblocking attribute_reference;
21/5
a call to a predefined boolean logical operator and where each operand is nonblocking-static;
22/5
an and then short-circuit control form where each operand is nonblocking-static;
23/5
a parenthesized nonblocking-static expression.
23.a/5
Reason: We define the term “nonblocking-static expression” so that nonblocking attribute_references can be used to define the value of other nonblocking aspects, but we don't allow anything else with a value not known at compile-time.
24/5
{AI12-0064-2} {AI12-0374-1} For a program unit, task entry, formal package, formal subprogram, formal object of an anonymous access-to-subprogram type, enumeration literal, and for a subtype (including a formal subtype), the following language-defined operational aspect is defined:
25/5
Nonblocking
This aspect specifies the blocking restriction for the entity; it shall be specified by an expression, called a nonblocking expression. If directly specified, the aspect_definition shall be a nonblocking-static expression. The expected type for the expression is the predefined type Boolean. [The aspect_definition can be omitted from the specification of this aspect; in that case the nonblocking expression for the entity is the enumeration literal True.]
25.a/5
Aspect Description for Nonblocking: Specifies that an associated subprogram does not block.
25.b/5
Proof: 13.1.1 allows omitting the aspect expression for any aspect with type Boolean; we take advantage of that here.
26/5
{AI12-0064-2} The Nonblocking aspect may be specified for all entities for which it is defined, except for protected operations and task entries. In particular, Nonblocking may be specified for generic formal parameters.
26.a/5
Ramification: The Nonblocking aspect cannot be specified for predefined operators or enumeration literals but we don't need to mention that above. One would have to declare a subprogram in order to specify the aspect in those cases, but that defines a user-defined subprogram which is itself not a predefined operator or an enumeration literal. 
27/5
{AI12-0064-2} When the nonblocking expression is static for an entity, the expression is evaluated to produce a static value for the aspect. When aspect Nonblocking is statically False for an entity, the entity might contain a potentially blocking operation; such an entity allows blocking. If the aspect is statically True for an entity, the entity is said to be nonblocking.
27.a/5
Discussion: We have to allow the aspect to be described as an expression inside of generic units, where the actual value of the aspect in an instance could be determined by the aspect of one or more actuals. Our intent is that the expression is always a static expression outside of any generic unit, and that in such contexts it is treated more like a static value than an expression.
27.b/5
Ramification: Specifying Nonblocking as False imposes no restrictions. Specifying Nonblocking as True imposes additional compile-time checks to prevent blocking, but does not prevent deadlock. A pragma Detect_Blocking can be used to ensure that Program_Error is raised in a deadlock situation. 
28/5
{AI12-0374-1} For a generic unit G, if the aspect Nonblocking is statically true for G (by inheritance or specification), then the nonblocking expression for G is the and of the nonblocking attribute for each formal parameter of G.
28.a/5
Reason: This means that an instance of this generic will be nonblocking only if all of the formal parameters are nonblocking (see below). This is the most usable definition. If one wants a generic whose instantiations will always be nonblocking, Nonblocking can be specified on the formal parameters.
29/5
{AI12-0064-2} For a generic instantiation and entities declared within such an instance, the aspect is determined by the nonblocking expression for the corresponding entity of the generic unit, with any Nonblocking attributes of the generic formal parameters replaced by the appropriate nonblocking expression of the corresponding actual parameters. If the aspect is directly specified for an instance, the specified expression shall be static and have the same value as the nonblocking expression of the instance (after replacement).
29.a/5
Reason: We want to allow confirming aspects for instances, but nothing else. The Legality Rules of the generic body were checked assuming the nonblocking expression of the generic unit, and if that is changed, the instance body might make calls that allow blocking in subprograms that are nonblocking.
29.b/5
Ramification: If the nonblocking expression of the instance is not static (if the instance is itself inside of a generic unit), then the Nonblocking aspect cannot be specified for the instance. 
30/5
{AI12-0064-2} For a (protected or task) entry, the Nonblocking aspect is the Boolean literal False.
30.a/5
Reason: An entry can be renamed as a procedure, so the value of the aspect has to be well-defined (as the attribute can be applied to a procedure). We do not want a nonblocking subprogram to be able to call an entry, no matter how it occurs, so the value ought to be False. Moreover, we do not want a subprogram that renames an entry to be able to override a nonblocking subprogram. We could have used individual rules for these cases, but there were already many of them, and this solution avoids the need for extra rules for entries.
31/5
{AI12-0064-2} For an enumeration literal, the Nonblocking aspect is the Boolean literal True.
31.a/5
Reason: Enumeration literals can be renamed as functions, and passed to generic formal functions, so we need to define the value of the aspect to ensure the other rules are meaningful. 
32/5
{AI12-0064-2} For a predefined operator of an elementary type, the Nonblocking aspect is the Boolean literal True. For a predefined operator of a composite type, the Nonblocking aspect of the operator is the same as the Nonblocking aspect for the type.
32.a/5
Reason: Predefined operators of elementary types can never include any potentially blocking operations, so we want them to declare that. Record equality can be composed of operations including user-defined "=" operators, which might allow blocking. Array equality might use some record equality. So we have to have the possibility of allowing blocking for them. We don't just copy the Nonblocking aspect of the type in every case, as someone could declare an elementary type to allow blocking. 
32.b/5
Ramification: It's not possible to specify the nonblocking expression of a predefined operator; if an operator is declared in order to do that, it is no longer predefined.
33/5
{AI12-0064-2} For a dereference of an access-to-subprogram type, the Nonblocking aspect of the designated subprogram is that of the access-to-subprogram type.
34/5
{AI12-0374-1} For the base type of a scalar (sub)type, the Nonblocking aspect is the Boolean literal True.
34.a/5
Reason: The first subtype of a scalar type can allow blocking (which can be useful so a predicate can allow blocking), but the base type is always Nonblocking. We need this so the Nonblocking value is well-defined for any subtype that is built from the base type (T'Base). T'Base of any scalar type, including a generic formal type, is always nonblocking. 
35/5
{AI12-0064-2} For an inherited primitive dispatching subprogram that is null or abstract, the subprogram is nonblocking if and only if a corresponding subprogram of at least one ancestor is nonblocking. For any other inherited subprogram, it is nonblocking if and only if the corresponding subprogram of the parent is nonblocking.
36/5
{AI12-0064-2} Unless directly specified, overridings of dispatching operations inherit this aspect.
37/5
{AI12-0064-2} {AI12-0374-1} Unless directly specified, for a formal subtype, formal package, or formal subprogram, the Nonblocking aspect is that of the actual subtype, package, or subprogram.
37.a/5
Reason: This means that Nonblocking legality checking for the actual parameters of the instance is only necessary when the aspect is explicitly specified for the formal type. 
38/5
{AI12-0064-2} Unless directly specified, for a derived type, the Nonblocking aspect is that of the parent type.
38.a/5
Discussion: The expressions that can be specified for a derived type are limited by a Legality Rule, see below. 
39/5
{AI12-0064-2} Unless directly specified, for any other program unit, type, or formal object, the Nonblocking aspect of the entity is determined by the Nonblocking aspect for the innermost program unit enclosing the entity.
40/5
{AI12-0064-2} If not specified for a library unit, the nonblocking expression is the Boolean literal True if the library unit is declared pure and is not a generic unit, or the Boolean literal False otherwise.
41/5
{AI12-0064-2} For a prefix S that denotes a subprogram (including a formal subprogram), the following attribute is defined:
42/5
S'Nonblocking
{AI12-0064-2} Denotes whether subprogram S is considered nonblocking; the type of this attribute is the predefined type Boolean.
43/5
The prefix S shall statically denote a subprogram.
43.a/5
Ramification: The evaluation of the prefix S will have no effect, which is necessary for S'Nonblocking to be static. For the intended use in aspect specifications, we don't want any evaluation, as it would happen at some freezing point. 
44/5
S'Nonblocking represents the nonblocking expression of S; evaluation of S'Nonblocking evaluates that expression. 
45/5
{AI12-0064-2} For a prefix P that denotes a package (including a formal package), the following attribute is defined:
46/5
P'Nonblocking
{AI12-0064-2} Denotes whether package P is considered nonblocking; the type of this attribute is the predefined type Boolean. P'Nonblocking represents the nonblocking expression of P; evaluation of P'Nonblocking evaluates that expression. 
47/5
{AI12-0064-2} For a prefix S that denotes a subtype (including formal subtypes), the following attribute is defined:
48/5
S'Nonblocking
{AI12-0064-2} {AI12-0319-1} {AI12-0374-1} Denotes whether default initialization, finalization, assignment, predefined operators, and (in the case of access-to-subprogram subtypes) a subprogram designated by a value of subtype S are considered nonblocking; the type of this attribute is the predefined type Boolean. S'Nonblocking represents the nonblocking expression of S; evaluation of S'Nonblocking evaluates that expression. 
49/5
{AI12-0319-1} For a prefix X that denotes an object, the following attribute is defined:
50/5
X'Nonblocking
{AI12-0319-1} {AI12-0374-1} Denotes whether the subtype of X is considered nonblocking; the type of this attribute is the predefined type Boolean. X'Nonblocking represents the nonblocking expression of X; evaluation of X'Nonblocking evaluates that expression. X'Nonblocking represents the nonblocking expression of X; evaluation of X'Nonblocking evaluates that expression.
50.a/5
To be honest: In the case when the prefix represents the Storage_Pool of some type, this is the specific type of the associated pool object, if known. 
50.b/5
Reason: This attribute, combined with rules found in 13.11, allow Acc'Storage_Pool'Nonblocking to describe whether the storage pool of an access type allows blocking. 
51/5
{AI12-0374-1} For a prefix X that denotes an object of a class-wide type T'Class, the following attribute is defined: 
52/5
X'Nonblocking(dispatching_operation_set)

{AI12-0374-1} X'Nonblocking(dispatching_operation_set) represents the and of the Nonblocking aspect of the tagged type T1 identified by the tag of X, and the Nonblocking aspects of the dispatching operations of T1 corresponding to the specified dispatching operations of T (or all dispatching operations of T if the set is the reserved word all). If a dispatching_selector_name within the set denotes multiple dispatching operations of T, the Nonblocking aspects of all of the corresponding dispatching operations of T1 are anded together. 
53/5
{AI12-0064-2} {AI12-0247-1} The following are defined to be potentially blocking operations:
53.a/5
Reason: The primary purpose of these rules is to define what operations are not allowed in a protected operation (blocking is not allowed). Some of these operations are not directly blocking. However, they are still treated as potentially blocking, because allowing them in a protected action might impose an undesirable implementation burden. 
54/5
a select_statement;
55/5
an accept_statement;
56/5
an entry_call_statement, or a call on a procedure that renames or is implemented by an entry;
57/5
a delay_statement;
58/5
an abort_statement;
59/5
task creation or activation;
60/5
during a protected action, an external call on a protected subprogram (or an external requeue) with the same target object as that of the protected action.
60.a/5
Reason: This is really a deadlocking call, rather than a blocking call, but we include it in this list for simplicity. 
61/5
{AI12-0064-2} If a language-defined subprogram allows blocking, then a call on the subprogram is a potentially blocking operation.
61.a/5
Ramification: Calls on other subprograms that allow blocking are not themselves potentially blocking; the execution of the body could execute a potentially blocking operation.
61.b/5
A user-defined instance of a language-defined generic creates user-defined subprograms for the purpose of this rule. A dispatching call to a language-defined abstract subprogram always calls a user-defined concrete subprogram, so that too is not potentially blocking for the purposes of this rule. 

Legality Rules

62/5
{AI12-0064-2} {AI12-0267-1} A parallel construct or a nonblocking program unit shall not contain, other than within nested units with Nonblocking specified as statically False, a call on a callable entity for which the Nonblocking aspect is statically False, nor shall it contain any of the following:
63/5
a select_statement;
64/5
an accept_statement;
65/5
a delay_statement;
66/5
an abort_statement;
67/5
task creation or activation.
67.a/5
Ramification: Implicit calls for finalization, storage pools, and the like are covered by the above prohibition. The rules above say “a call”, not “an explicit call”. Such calls are considered statically bound when that is possible, that is, when the controlling object has a known specific type (even if the actual implementation uses dispatching). 
67.b/5
Discussion: We don't need to worry specially about entry calls (even if the entry has been renamed as a procedure), as they will be detected by the prohibition against calls to entities with the Nonblocking aspect False.
67.c/5
Similarly, we don't need to specially worry about subprograms of limited interfaces that are implemented by entries, as any such subprogram necessarily has the value statically False for the Nonblocking aspect, and thus is already covered by the prohibition against calling such subprograms. 
68/5
{AI12-0064-2} For the purposes of the above rule, an entry_body is considered nonblocking if the immediately enclosing protected unit is nonblocking.
68.a/5
Reason: An entry always allows blocking (by rule); but we want to be able to compile-time check for most violations of prohibition against potentially blocking operations in a protected action (see 9.5.1). We do that by using the nonblocking status of the protected unit as the controlling factor, and enforce that by not allowing the specification of the Nonblocking aspect for any protected operation. 
69/5
{AI12-0374-1} For a subtype for which aspect Nonblocking is True, any predicate expression that applies to the subtype shall only contain constructs that are allowed immediately within a nonblocking program unit.
70/5
{AI12-0064-2} A subprogram shall be nonblocking if it overrides a nonblocking dispatching operation. An entry shall not implement a nonblocking procedure. If an inherited dispatching subprogram allows blocking, then the corresponding subprogram of each ancestor shall allow blocking.
70.a/5
Discussion: Rules elsewhere in the standard (4.6 and 3.10.2) ensure that access-to-subprogram conversion and the Access attribute enforce nonblocking. 
70.b/5
Ramification: A nonblocking subprogram can override one that allows blocking, but the reverse is illegal. Thus one can declare a Finalize subprogram to be nonblocking, even though it overrides a routine that allows blocking. (This works because a nonblocking subprogram allows a strict subset of the operations allowed in allows blocking subprograms, so calling such a subprogram as if it allows blocking — as is necessary in a dispatching call — is harmless.) 
71/5
{AI12-0064-2} It is illegal to specify aspect Nonblocking for the full view of a type that has a partial view.
71.a/5
Ramification: The aspect should be specified on the partial view for such a type. This is necessary to prevent the predefined equality operator from being nonblocking in the partial view and allowing blocking in the full view. 
72/5
{AI12-0064-2} {AI12-0374-1} Aspect Nonblocking shall be specified for the first subtype of a derived type only if it fully conforms to the nonblocking expression of the ancestor subtype or if it is specified to have the Boolean literal True. Aspect Nonblocking shall be specified for a nonfirst subtype S only if it fully conforms to the nonblocking expression of the subtype identified in the subtype_indication defining S or if it is specified to have the Boolean literal True. Aspect Nonblocking shall be specified for a first subtype S that completes an incomplete or partial view P only if it fully conforms to the nonblocking expression of the subtype P or if it is specified to have the Boolean literal True.
72.a/5
Reason: Boolean-valued aspects have a similar rule to the first rule here (see 13.1.1), we want this one to work similarly. For the other rules, we need non-first subtypes and completions to allow blocking only if the original first subtype allows blocking, as that allows the programmer to know that any operation on any subtype of a type are nonblocking if the first subtype is nonblocking. 
73/5
{AI12-0064-2} If aspect Nonblocking is specified for an entity that is not a generic unit or declared inside of a generic unit, the aspect_definition shall be a static expression.
74/5
{AI12-0064-2} If the prefix of a Nonblocking attribute_reference denotes a generic unit G, the reference shall occur within the declarative region of G.
74.a/5
Reason: We want the value of Nonblocking attributes to be static so long as they occur outside of any generic unit. The Nonblocking aspect of a generic unit will often depend on the actual parameters of the unit, so it cannot be static (or have any well-defined value). We need this latter rule in case the attribute of a generic is used outside of the generic. Note that the previous rule makes it illegal to use such an attribute to specify aspect Nonblocking outside of a generic, but we don't want to allow any other uses since it does not have a known value until instantiated.
74.b/5
Ramification: This rule does not apply to instances of generic units and entities declared within them. 
75/5
{AI12-0319-1} For a composite type that is nonblocking:
76/5
All component subtypes shall be nonblocking;
77/5
For a record type or extension, every call in the default_expression of a component (including discriminants) shall call an operation that is nonblocking;
78/5
For a controlled type, the Initialize, Finalize, and Adjust (if any) subprograms shall be nonblocking.
78.a/5
Reason: These rules ensure that if a type is nonblocking, the default initialization, finalization, and assignment of the type are also nonblocking. This allows the use of the nonblocking attribute of a generic formal type to describe whether these operations of the type allow blocking.
78.b/5
Default initialization, finalization, and assignment of elementary types are always nonblocking, so we don't need any rules for those. 
79/5
{AI12-0064-2} The predefined equality operator for a composite type is illegal if it is nonblocking and, for a record type, it is not overridden by a primitive equality operator, and:
80/5
for a record type, the parent primitive "=" allows blocking; or
81/5
any component that has a record type that has a primitive "=" that allows blocking; or
82/5
any component that has a non-record type that has a predefined "=" that allows blocking.
82.a/5
Ramification: This applies to both record and array "=".
82.b/5
This check occurs when the equality operator is declared, so this rule effectively makes the type illegal if the rule is violated. 
82.c/5
Reason: We don't need to check this when the operator is overridden for a record type, as the body of the new definition of equality will enforce the rules, and there is no case where the predefined operator will re-emerge. We do have to check this for array types even if the operator is overridden, as the predefined operator will re-emerge in generics and record equality.
83/5
{AI12-0064-2} In a generic instantiation (after replacement in the nonblocking expressions by values of the actuals as described previously):
84/5
the actual subprogram corresponding to a nonblocking formal subprogram shall be nonblocking [(an actual that is an entry is not permitted in this case)];
85/5
the actual type corresponding to a nonblocking formal private, derived, array, or access-to-subprogram type shall be nonblocking;
85.a/5
Ramification: We do not require matching for formal scalar or access-to-object types, as their predefined operators are always nonblocking (and they re-emerge in the generic unit) — the nonblocking status of the type has no impact. 
86/5
the actual object corresponding to a formal object of a nonblocking access-to-subprogram type shall be of a nonblocking access-to-subprogram type;
87/5
the actual instance corresponding to a nonblocking formal package shall be nonblocking.
88/5
{AI12-0064-2} In addition to the places where Legality Rules normally apply (see 12.3), the above rules also apply in the private part of an instance of a generic unit.
88.a/5
Ramification: For a generic formal parameter to be nonblocking (thus, for these rules to apply), it has to explicitly specify aspect Nonblocking to be True. In particular, these rules do not apply when it specifies aspect Nonblocking to be an expression involving attribute Nonblocking of a generic formal parameter. However, in such a case, these rules do apply in the instance of the specification of the generic unit (the normal re-checking is needed). For instance, the body of an expression function might make a prohibited call. 
89/5
{AI12-0064-2} A program unit P declared inside of a generic unit but not in a generic body or that is a generic specification not declared in a generic unit is considered nonblocking for the purposes of checking the restrictions on a nonblocking unit only if the value of its Nonblocking aspect is statically True. For the purposes of checks in P, a call to a subprogram is considered nonblocking unless the value of its Nonblocking aspect is statically False.
89.a/5
Reason: This is a typical “assume-the-best” rule. We only make checks if we know the nonblocking status of both P and the called subprogram. All other checks will be performed when the generic unit is instantiated. We used the awkward “inside of a generic unit but not in a generic body” so that a generic specification declared inside of a generic body uses the following “assume-the-worst” rule. 
90/5
{AI12-0064-2} A program unit P declared inside of a generic body or that is a generic body is considered nonblocking for the purposes of checking the restrictions on a nonblocking unit unless the value of its Nonblocking aspect is statically False. For the purposes of checks in P, a call to a subprogram is considered to allow blocking unless:
91/5
the value of its Nonblocking aspect is statically True, or
92/5
its nonblocking expression (that is, Nonblocking aspect) conforms exactly to that of P, or conforms to some part of the nonblocking expression of P that is combined with the remainder of the nonblocking expression of P by one or more and or and then operations. 
92.a/5
Ramification: That is, if the aspect of the program unit is specified (directly or via inheritance) with any non-static Nonblocking aspects, it is considered to be a nonblocking program unit for the purposes of making checks. This is a typical “assume-the-worst” rule. 
92.b/5
Reason: The second part allows calls on subprograms with Nonblocking aspects of Formal'Nonblocking, so long as the Nonblocking aspect of P is some formula that contains Formal'Nonblocking combined with and. This ensures that P will always allow blocking if the actual for Formal turns out to allow blocking.
92.c/5
Without this rule, we'd allow calls on formals in any body subprogram, even if the subprogram did not include the formal in its Nonblocking aspect. For instance:
92.d/5
procedure Blah with Formal1'Blocking is
begin
   Formal2;
end Blah;
92.e/5
If Formal1 is nonblocking and Formal2 allows blocking, then we'd have a nonblocking routine calling a routine that might block. That has to be prevented as this is “assume-the-worst” checking. 
92.f/5
To be honest: {AI12-0319-1} For checking in P, default initialization, finalization, assignment, or conversion to a formal subtype F is considered to call subprograms that have the nonblocking aspect of F'Nonblocking, and this is checked for conformance against that of P as described above. Note that the nonblocking aspect includes the evaluation of any predicate for the subtype.
92.g/5
{AI12-0319-1} Similarly, for checking in P, the implicit calls associated with an allocator of an access type A or a use of attribute A'Storage_Size are considered to call subprograms that have the nonblocking aspect of A'Storage_Pool'Nonblocking, and this is checked for conformance against that of P as described above. 
NOTES
93/3
18  {AI05-0030-2} {AI05-0215-1} The synchronization_kind By_Protected_Procedure implies that the operation will not block. 

Wording Changes from Ada 95

93.a/2
{AI95-00345-01} Added a Legality Rule to make it crystal-clear that the protected object of an entry or procedure call must be a variable. This rule was implied by the Dynamic Semantics here, along with the Static Semantics of 3.3, but it is much better to explicitly say it. While many implementations have gotten this wrong, this is not an incompatibility — allowing updates of protected constants has always been wrong. 

Extensions to Ada 2005

93.b/3
{AI05-0030-2} {AI05-0215-1} Added the Synchronization aspect to allow specifying that an interface procedure is really an entry or a protected procedure.

Wording Changes from Ada 2005

93.c/3
{AI05-0225-1} Correction: Clarified that the target object of any name denoted a protected procedure or entry can never be a constant (other than for the 'Count attribute). This closes holes involving calls to access-to-protected, renaming as a procedure, and generic formal subprograms. 

Inconsistencies With Ada 2012

93.d/5
{AI12-0064-2} Calls on procedures that rename an entry or are implemented by an entry are now defined to be potentially blocking. This means that such a call now might raise Program_Error. However, it never made sense for some entry calls to be excluded from being potentially blocking, and we expect that most implementations already treated all entry calls the same way. Thus do not expect this wording change to actually change the behavior of any implementation, and thus no program will change. 

Incompatibilities With Ada 2012

93.e/5
{AI12-0166-1} Correction: Internal protected calls are now prohibited in preconditions and default expressions of protected operations. These were allowed in Ada 2012, but as they cause race conditions and as most existing Ada 95 compilers crash when given such a default parameter, we expect such code to be extremely rare.

Extensions to Ada 2012

93.f/5
{AI12-0064-2} {AI12-0319-1} {AI12-0374-1} Aspect Nonblocking is new; it allows compile-time checks to prevent using potentially blocking operations in contexts where that is not allowed. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe