9.5 Intertask Communication
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
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:
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;
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;
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;
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.
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
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).
Dynamic Semantics
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.
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.
Syntax
synchronization_kind ::= By_Entry | By_Protected_Procedure | Optional
Static Semantics
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):
Synchronization
If specified, the aspect definition shall be a
synchronization_kind.
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
The
synchronization_kind
By_Protected_Procedure shall not be applied to a primitive procedure
of a task interface.
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).
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.
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
An
expression
is
nonblocking-static if it is one of the following:
a static expression;
a call to a predefined boolean logical operator
and where each operand is nonblocking-static;
an and then short-circuit control form where
each operand is nonblocking-static;
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:
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.
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.
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.
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.
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).
For a (protected or task) entry, the Nonblocking
aspect is the Boolean literal False.
For an enumeration literal, the Nonblocking
aspect is the Boolean literal True.
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.
For a dereference of an access-to-subprogram
type, the Nonblocking aspect of the designated subprogram is that of
the access-to-subprogram type.
For the base type of a scalar (sub)type,
the Nonblocking aspect is the Boolean literal True.
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.
Unless directly specified, overridings
of dispatching operations inherit this aspect.
Unless directly specified, for a formal
subtype, formal package, or formal subprogram, the Nonblocking aspect
is that of the actual subtype, package, or subprogram.
Unless directly specified, for a derived
type, the Nonblocking aspect is that of the parent type.
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.
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.
For a
prefix
S that denotes a subprogram (including a formal subprogram), the following
attribute is defined:
S'Nonblocking
Denotes whether subprogram S
is considered nonblocking; the type of this attribute is the predefined
type Boolean.
The
prefix
S shall statically denote a subprogram.
S'Nonblocking represents the nonblocking
expression of S; evaluation of S'Nonblocking evaluates that expression.
For a
prefix
P that denotes a package (including a formal package), the following
attribute is defined:
P'Nonblocking
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.
For a
prefix
S that denotes a subtype (including formal subtypes), the following attribute
is defined:
S'Nonblocking
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.
For a
prefix
X that denotes an object, the following attribute is defined:
X'Nonblocking
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.
For a
prefix
X that denotes an object of a class-wide type T'Class, the following
attribute is defined:
X'Nonblocking(dispatching_operation_set)
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.
The following are defined
to be
potentially blocking operations:
task creation or activation;
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.
If a language-defined subprogram allows blocking,
then a call on the subprogram is a potentially blocking operation.
Legality Rules
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:
task creation or activation.
For the purposes of the above rule, an
entry_body
is considered nonblocking if the immediately enclosing protected unit
is nonblocking.
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.
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.
It is illegal to specify aspect Nonblocking for the
full view of a type that has a partial view.
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.
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.
If the prefix of a Nonblocking
attribute_reference
denotes a generic unit
G, the reference shall occur within the
declarative region of
G.
For a composite type
that is nonblocking:
All component subtypes shall be nonblocking;
For a record type or extension, every call in the
default_expression
of a component (including discriminants) shall call an operation that
is nonblocking;
For a controlled type, the Initialize, Finalize,
and Adjust (if any) subprograms shall be nonblocking.
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:
for a record type, the parent primitive "="
allows blocking; or
any component that has a record type that has a
primitive "=" that allows blocking; or
any component that has a non-record type that has
a predefined "=" that allows blocking.
In a generic instantiation
(after replacement in the nonblocking expressions by values of the actuals
as described previously):
the actual subprogram corresponding to a nonblocking
formal subprogram shall be nonblocking (an actual that is an entry is
not permitted in this case);
the actual type corresponding to a nonblocking
formal private, derived, array, or access-to-subprogram type shall be
nonblocking;
the actual object corresponding to a formal object
of a nonblocking access-to-subprogram type shall be of a nonblocking
access-to-subprogram type;
the actual instance corresponding to a nonblocking
formal package shall be nonblocking.
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.
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.
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:
the value of its Nonblocking aspect is statically
True, or
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.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe