9.1 Task Units and Task Objects
1
A task unit is declared by a
task declaration, which has a corresponding
task_body.
A task declaration may be a
task_type_declaration,
in which case it declares a named task type; alternatively, it may be
a
single_task_declaration, in which case it
defines an anonymous task type, as well as declaring a named task object
of that type.
Syntax
2/2
task_type_declaration ::=
task type defining_identifier [
known_discriminant_part] [
is
[
new interface_list with]
task_definition];
3/2
single_task_declaration ::=
task defining_identifier [
is
[
new interface_list with]
task_definition];
4
task_definition ::=
{
task_item}
[
private
{
task_item}]
end [
task_identifier]
5/1
task_item ::= entry_declaration |
aspect_clause
6
task_body ::=
task body defining_identifier is
declarative_part
begin
handled_sequence_of_statements
end [
task_identifier];
7
If a task_identifier
appears at the end of a task_definition or
task_body, it shall repeat the defining_identifier.
Legality Rules
8/2
This paragraph was
deleted.
Static Semantics
9
A
task_definition defines
a task type and its first subtype.
The first list
of
task_items of a
task_definition,
together with the
known_discriminant_part,
if any, is called the visible part of the task unit.
The
optional list of
task_items after the reserved
word
private is called the private part of the task unit.
9.1/1
For a task declaration without a task_definition,
a task_definition without task_items
is assumed.
9.2/2
For a task declaration with an
interface_list,
the task type inherits user-defined primitive subprograms from each progenitor
type (see
3.9.4), in the same way that a
derived type inherits user-defined primitive subprograms from its progenitor
types (see
3.4). If the first parameter of
a primitive inherited subprogram is of the task type or an access parameter
designating the task type, and there is an
entry_declaration
for a single entry with the same identifier within the task declaration,
whose profile is type conformant with the prefixed view profile of the
inherited subprogram, the inherited subprogram is said to be
implemented
by the conforming task entry.
Legality Rules
9.3/2
A task declaration requires
a completion, which shall be a
task_body,
and every
task_body shall be the completion
of some task declaration.
9.4/2
Each interface_subtype_mark
of an interface_list appearing within a task
declaration shall denote a limited interface type that is not a protected
interface.
9.5/2
The prefixed view profile of an explicitly declared
primitive subprogram of a tagged task type shall not be type conformant
with any entry of the task type, if the first parameter of the subprogram
is of the task type or is an access parameter designating the task type.
9.6/2
For each primitive
subprogram inherited by the type declared by a task declaration, at most
one of the following shall apply:
9.7/2
- the inherited subprogram is overridden
with a primitive subprogram of the task type, in which case the overriding
subprogram shall be subtype conformant with the inherited subprogram
and not abstract; or
9.8/2
- the inherited subprogram is implemented
by a single entry of the task type; in which case its prefixed view profile
shall be subtype conformant with that of the task entry.
9.9/2
If neither applies, the inherited subprogram shall
be a null procedure.
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.
Dynamic Semantics
10
The elaboration of a task declaration
elaborates the
task_definition.
The
elaboration of a
single_task_declaration also
creates an object of an (anonymous) task type.
11
The elaboration of a
task_definition
creates the task type and its first subtype; it also includes the elaboration
of the
entry_declarations in the given order.
12/1
As part of the initialization
of a task object, any
aspect_clauses and any
per-object constraints associated with
entry_declarations
of the corresponding
task_definition are elaborated
in the given order.
13
The elaboration of a
task_body
has no effect other than to establish that tasks of the type can from
then on be activated without failing the Elaboration_Check.
14
The execution of a
task_body
is invoked by the activation of a task of the corresponding type (see
9.2).
15
The content of a task
object of a given task type includes:
16
- The values of the discriminants of
the task object, if any;
17
- An entry queue for each entry of the
task object;
18
- A representation of the state of the
associated task.
19/2
2 Other than in an
access_definition,
the name of a task unit within the declaration or body of the task unit
denotes the current instance of the unit (see
8.6),
rather than the first subtype of the corresponding task type (and thus
the name cannot be used as a
subtype_mark).
20
3 The notation of a
selected_component
can be used to denote a discriminant of a task (see
4.1.3).
Within a task unit, the name of a discriminant of the task type denotes
the corresponding discriminant of the current instance of the unit.
21/2
4 A task type is a limited type (see
7.5),
and hence precludes use of
assignment_statements
and predefined equality operators. If an application needs to store and
exchange task identities, it can do so by defining an access type designating
the corresponding task objects and by using access values for identification
purposes. Assignment is available for such an access type as for any
access type. Alternatively, if the implementation supports the Systems
Programming Annex, the Identity attribute can be used for task identification
(see
C.7.1).
Examples
22
Examples of declarations
of task types:
23
task type Server is
entry Next_Work_Item(WI : in Work_Item);
entry Shut_Down;
end Server;
24/2
task type Keyboard_Driver(ID : Keyboard_ID := New_ID)
is
new Serial_Device
with --
see 3.9.4
entry Read (C :
out Character);
entry Write(C :
in Character);
end Keyboard_Driver;
25
Examples of declarations of single tasks:
26
task Controller is
entry Request(Level)(D : Item); -- a family of entries
end Controller;
27
task Parser is
entry Next_Lexeme(L : in Lexical_Element);
entry Next_Action(A : out Parser_Action);
end;
28
task User; -- has no entries
29
Examples of task objects:
30
Agent : Server;
Teletype : Keyboard_Driver(TTY_ID);
Pool : array(1 .. 10) of Keyboard_Driver;
31
Example of access
type designating task objects:
32
type Keyboard is access Keyboard_Driver;
Terminal : Keyboard := new Keyboard_Driver(Term_ID);