9.1 Task Units and Task Objects
1
{task declaration} 
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
{
AI95-00345-01} 
task_type_declaration ::= 
   task type defining_identifier [
known_discriminant_part] [
is
     [new interface_list with]
     task_definition];
 
3/2
{
AI95-00399-01} 
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
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.{
AI95-00345-01} 
{requires a completion 
(task_declaration}) [partial]} A task 
declaration requires a completion[, which shall be a task_body,] 
and every task_body shall be the completion 
of some task declaration.  
8.a/2
This paragraph 
was deleted.To be honest: The 
completion can be a pragma Import, if the 
implementation supports it. 
Static Semantics
9
A 
task_definition defines 
a task type and its first subtype. 
{visible 
part (of a task unit) [partial]} 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. [
{private 
part (of a task unit) [partial]} The optional 
list of 
task_items after the reserved word 
private is called the private part of the task unit.] 
 
9.a
Proof: Private part is defined in Section 
8. 
9.1/1
  {
8652/0029} 
{
AI95-00116-01} 
For a task declaration without a task_definition, 
a task_definition without task_items 
is assumed. 
9.2/2
  {
AI95-00345-01} 
{
AI95-00397-01} 
{
AI95-00399-01} 
{
AI95-00419-01} 
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.{implemented 
(by a task entry) [partial]} {type 
conformance (required)}  
9.b/2
Ramification: The 
inherited subprograms can only come from an interface given as part of 
the task declaration. 
Legality Rules
9.3/2
  {
AI95-00345-01} 
{requires a completion 
(task_declaration}) [partial]} 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.c/2
To be honest: The 
completion can be a pragma Import, if the 
implementation supports it. 
9.4/2
  {
AI95-00345-01} 
{
AI95-00399-01} 
[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.d/2
Proof: 3.9.4 
requires that an interface_list only name 
interface types, and limits the descendants of the various kinds of interface 
types. Only a limited, task, or synchronized interface can have a task 
type descendant. Nonlimited or protected interfaces are not allowed, 
as they offer operations that a task does not have.  
9.5/2
  {
AI95-00397-01} 
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.e/2
Reason: This prevents 
the existence of two operations with the same name and profile which 
could be called with a prefixed view. If the operation was inherited, 
this would be illegal by the following rules; this rule puts inherited 
and non-inherited routines on the same footing. Note that this only applies 
to tagged task types (that is, those with an interface in their declaration); 
we do that as there is no problem with prefixed view calls of primitive 
operations for “normal” task types, and having this rule 
apply to all tasks would be incompatible with Ada 95. 
9.6/2
  {
AI95-00345-01} 
{
AI95-00399-01} 
For each primitive subprogram inherited by the 
type declared by a task declaration, at most one of the following shall 
apply: 
9.7/2
- {AI95-00345-01} 
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{subtype conformance (required)} 
 
9.8/2
- {AI95-00345-01} 
{AI95-00397-01} 
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. {subtype 
conformance (required)} 
 
9.f/2
Ramification: An 
entry may implement two subprograms from the ancestors, one whose first 
parameter is of type T and one whose first parameter is of type 
access T. That doesn't cause implementation problems because 
“implemented by” (unlike “overridden’) probably 
entails the creation of wrappers. 
9.9/2
  If neither applies, the inherited 
subprogram shall be a null procedure. {generic 
contract issue [partial]} 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.  
9.g/2
Reason: Each inherited 
subprogram can only have a single implementation (either from overriding 
a subprogram or implementing an entry), and must have an implementation 
unless the subprogram is a null procedure. 
Dynamic Semantics
10
[
{elaboration (task 
declaration) [partial]} The elaboration 
of a task declaration elaborates the 
task_definition. 
{elaboration (single_task_declaration) 
[partial]} The elaboration of a 
single_task_declaration 
also creates an object of an (anonymous) task type.] 
 
10.a
Proof: This is redundant with the general 
rules for the elaboration of a full_type_declaration 
and an object_declaration. 
11
{elaboration (task_definition) 
[partial]} [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
 {
8652/0009} 
{
AI95-00137-01} 
{initialization (of a task object) 
[partial]} As part of the initialization of 
a task object, any 
aspect_clauses representation_clauses 
and any per-object constraints associated with 
entry_declarations 
of the corresponding 
task_definition are elaborated 
in the given order. 
 
12.a/1
Reason: The only aspect_clauses representation_clauses 
defined for task entries are ones that specify the Address of an entry, 
as part of defining an interrupt entry. These clearly need to be elaborated 
per-object, not per-type. Normally the address will be a function of 
a discriminant, if such an Address clause is in a task type rather than 
a single task declaration, though it could rely on a parameterless function 
that allocates sequential interrupt vectors.
12.b
We do not mention representation pragmas, since 
each pragma may have its own elaboration rules. 
13
{elaboration (task_body) 
[partial]} 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; 
 
17.a
Ramification: "For each entry" 
implies one queue for each single entry, plus one for each entry of each 
entry family. 
18
- A representation of the state of the 
associated task. 
 
19/2
2  {
AI95-00382-01} 
Other than in an access_definition, 
the name of a task unit within Within 
the declaration or body of 
the a 
task unit
, the name 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). 
 
19.a/2
Discussion: {
AI95-00382-01} 
It can be used as a subtype_mark 
in an anonymous access type. In addition However, 
it is possible to refer to some other subtype of the task type within 
its body, presuming such a subtype has been declared between the 
task_type_declaration 
and the 
task_body. 
 
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  {
AI95-00287-01} 
A task type is a limited type (see 
7.5), and 
hence 
precludes use of assignment_statements 
and has neither an assignment operation 
nor 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 C.7). 
 
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
{
AI95-00433-01} 
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);
Extensions to Ada 83
32.a/1
{
extensions to Ada 83} 
The 
syntax rules for task declarations are modified to allow a 
known_discriminant_part, 
and to allow a private part. They are also modified to allow 
entry_declarations 
and 
aspect_clauses representation_clauses 
to be mixed. 
 
Wording Changes from Ada 83
32.b
The syntax rules for tasks have been split up 
according to task types and single tasks. In particular: The syntax rules 
for task_declaration and task_specification 
are removed. The syntax rules for task_type_declaration, 
single_task_declaration, task_definition 
and task_item are new.
32.c
The syntax rule for task_body 
now uses the nonterminal handled_sequence_of_statements.
32.d
The declarative_part 
of a task_body is now required; that doesn't 
make any real difference, because a declarative_part 
can be empty. 
Extensions to Ada 95
32.e/2
{
AI95-00345-01} 
{
AI95-00397-01} 
{
AI95-00399-01} 
{
AI95-00419-01} 
{extensions to Ada 95} Task 
types and single tasks can be derived from one or more interfaces. Entries 
of the task type can implement the primitive operations of an interface. 
Overriding_indicators can be used to specify 
whether or not an entry implements a primitive operation.  
Wording Changes from Ada 95
32.f/2
{
8652/0029} 
{
AI95-00116-01} 
Corrigendum: Clarified that a task type 
has an implicit empty task_definition if none 
is given. 
32.g/2
{
8652/0009} 
{
AI95-00137-01} 
Corrigendum: Changed representation clauses 
to aspect clauses to reflect that they are used for more than just representation. 
32.h/2
{
AI95-00287-01} 
Revised the note on operations of task types to 
reflect that limited types do have an assignment operation, but not copying 
(assignment_statements). 
32.i/2
{
AI95-00382-01} 
Revised the note on use of the name of a task type 
within itself to reflect the exception for anonymous access types.