Ada Resource Association
News and resources for the Ada programming language
Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

9.1 Task Units and Task Objects

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. 


task_type_declaration ::= 
   task type defining_identifier [known_discriminant_part]
        [aspect_specification] [is
     [new interface_list with]
single_task_declaration ::= 
   task defining_identifier 
     [new interface_list with]
task_definition ::= 
  [ private
  end [task_identifier]
task_item ::= entry_declaration | aspect_clause
task_body ::= 
   task body defining_identifier
   end [task_identifier];
If a task_identifier appears at the end of a task_definition or task_body, it shall repeat the defining_identifier.
Paragraph 8 was deleted.

Static Semantics

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. 
  For a task declaration without a task_definition, a task_definition without task_items is assumed.
  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 using an implicitly declared nonabstract subprogram which has the same profile as the inherited subprogram and which overrides it.

Legality Rules

  A task declaration requires a completion, which shall be a task_body, and every task_body shall be the completion of some task declaration. 
  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. 
  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 subprogram has the same defining name as the entry and the first parameter of the subprogram is of the task type or is an access parameter designating the task type.
  For each primitive subprogram inherited by the type declared by a task declaration, at most one of the following shall apply:
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
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.
  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

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. 
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.
 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. 
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.
The execution of a task_body is invoked by the activation of a task of the corresponding type (see 9.2).
The content of a task object of a given task type includes: 
The values of the discriminants of the task object, if any;
An entry queue for each entry of the task object;
A representation of the state of the associated task. 
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).
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.
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 of declarations of task types: 
task type Server is
   entry Next_Work_Item(WI : in Work_Item);
   entry Shut_Down;
end Server;
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;
Examples of declarations of single tasks: 
task Controller is
   entry Request(Level)(D : Item);  --  a family of entries
end Controller;
task Parser is
   entry Next_Lexeme(L : in  Lexical_Element);
   entry Next_Action(A : out Parser_Action);
task User;  --  has no entries
Examples of task objects: 
Agent    : Server;
Teletype : Keyboard_Driver(TTY_ID);
Pool     : array(1 .. 10) of Keyboard_Driver;
Example of access type designating task objects: 
type Keyboard is access Keyboard_Driver;
Terminal : Keyboard := new Keyboard_Driver(Term_ID);

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