task_type_declaration ::= task type defining_identifier [known_discriminant_part] [is task_definition];
single_task_declaration ::= task defining_identifier [is task_definition];
task_definition ::= {task_item} [ private {task_item}] end [task_identifier]
task_item ::= entry_declaration | representation_clause
task_body ::= task body defining_identifier is declarative_part begin handled_sequence_of_statements end [task_identifier];
Legality Rules
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 entry Read (C : out Character); entry Write(C : in Character); end Keyboard_Driver;
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); end;
task User; -- has no entries
Agent : Server; Teletype : Keyboard_Driver(TTY_ID); Pool : array(1 .. 10) of Keyboard_Driver;
type Keyboard is access Keyboard_Driver; Terminal : Keyboard := new Keyboard_Driver(Term_ID);
Dynamic Semantics
procedure P is A, B : Server; -- elaborate the task objects A, B C : Server; -- elaborate the task object C begin -- the tasks A, B, C are activated together -- before the first statement ... end;
Dynamic Semantics
Examples
declare type Global is access Server; -- see section Task Units and Task Objects A, B : Server; G : Global; begin -- activation of A and B declare type Local is access Server; X : Global := new Server; -- activation of X.all L : Local := new Server; -- activation of L.all C : Server; begin -- activation of C G := X; -- both G and X designate the same task object ... end; -- await termination of C and L.all (but not X.all) ... end; -- await termination of A, B, and G.all
protected_type_declaration ::= protected type defining_identifier [known_discriminant_part] is protected_definition;
single_protected_declaration ::= protected defining_identifier is protected_definition;
protected_definition ::= { protected_operation_declaration } [ private { protected_element_declaration } ] end [protected_identifier]
protected_operation_declaration ::= subprogram_declaration | entry_declaration | representation_clause
protected_element_declaration ::= protected_operation_declaration | component_declaration
protected_body ::= protected body defining_identifier is { protected_operation_item } end [protected_identifier];
protected_operation_item ::= subprogram_declaration | subprogram_body | entry_body | representation_clause
Legality Rules
protected type Resource is entry Seize; procedure Release; private Busy : Boolean := False; end Resource;
protected body Resource is entry Seize when not Busy is begin Busy := True; end Seize;
procedure Release is begin Busy := False; end Release; end Resource;
protected Shared_Array is -- Index, Item, and Item_Array are global types function Component (N : in Index) return Item; procedure Set_Component(N : in Index; E : in Item); private Table : Item_Array(Index) := (others => Null_Item); end Shared_Array;
protected body Shared_Array is function Component(N : in Index) return Item is begin return Table(N); end Component;
procedure Set_Component(N : in Index; E : in Item) is begin Table(N) := E; end Set_Component; end Shared_Array;
Control : Resource; Flags : array(1 .. 100) of Resource;
Shared_Array.Set_Component(N, E); E := Shared_Array.Component(M); Control.Release;
entry_declaration ::= entry defining_identifier [(discrete_subtype_definition)] parameter_profile;
accept_statement ::= accept entry_direct_name [(entry_index)] parameter_profile [do handled_sequence_of_statements end [entry_identifier]];
entry_index ::= expression
entry_body ::= entry defining_identifier entry_body_formal_part entry_barrier is declarative_part begin handled_sequence_of_statements end [entry_identifier];
entry_body_formal_part ::= [(entry_index_specification)] parameter_profile
entry_barrier ::= when condition
entry_index_specification ::= for defining_identifier in discrete_subtype_definition
Name Resolution Rules
entry Read(V : out Item); entry Seize; entry Request(Level)(D : Item); -- a family of entries
accept Shut_Down;
accept Read(V : out Item) do V := Local_Item; end Read;
accept Request(Low)(D : Item) do ... end Request;
entry_call_statement ::= entry_name [actual_parameter_part];Name Resolution Rules
Agent.Shut_Down; -- see section Task Units and Task Objects Parser.Next_Lexeme(E); -- see section Task Units and Task Objects Pool(5).Read(Next_Char); -- see section Task Units and Task Objects Controller.Request(Low)(Some_Item); -- see section Task Units and Task Objects Flags(3).Seize; -- see section Protected Units and Protected Objects
requeue_statement ::= requeue entry_name [with abort];Name Resolution Rules
requeue Request(Medium) with abort; -- requeue on a member of an entry family -- of the current task, see section Task Units and Task Objects
requeue Flags(I).Seize; -- requeue on an entry of an array -- component, see section Protected Units and Protected Objects
delay_statement ::= delay_until_statement | delay_relative_statement
delay_until_statement ::= delay until delay_expression;
delay_relative_statement ::= delay delay_expression;Name Resolution Rules
package Ada.Calendar is type Time is private;
subtype Year_Number is Integer range 1901 .. 2099; subtype Month_Number is Integer range 1 .. 12; subtype Day_Number is Integer range 1 .. 31; subtype Day_Duration is Duration range 0.0 .. 86_400.0;
function Clock return Time;
function Year (Date : Time) return Year_Number; function Month (Date : Time) return Month_Number; function Day (Date : Time) return Day_Number; function Seconds(Date : Time) return Day_Duration;
procedure Split (Date : in Time; Year : out Year_Number; Month : out Month_Number; Day : out Day_Number; Seconds : out Day_Duration);
function Time_Of(Year : Year_Number; Month : Month_Number; Day : Day_Number; Seconds : Day_Duration := 0.0) return Time;
function "+" (Left : Time; Right : Duration) return Time; function "+" (Left : Duration; Right : Time) return Time; function "-" (Left : Time; Right : Duration) return Time; function "-" (Left : Time; Right : Time) return Duration;
function "<" (Left, Right : Time) return Boolean; function "<="(Left, Right : Time) return Boolean; function ">" (Left, Right : Time) return Boolean; function ">="(Left, Right : Time) return Boolean;
Time_Error : exception;
private ... -- not specified by the language end Ada.Calendar;Dynamic Semantics
delay 3.0; -- delay 3.0 seconds
declare use Ada.Calendar; Next_Time : Time := Clock + Period; -- Period is a global constant of type Duration begin loop -- repeated every Period seconds delay until Next_Time; ... -- perform some actions Next_Time := Next_Time + Period; end loop; end;
select_statement ::= selective_accept | timed_entry_call | conditional_entry_call | asynchronous_selectExamples
select accept Driver_Awake_Signal; or delay 30.0*Seconds; Stop_The_Train; end select;
selective_accept ::= select [guard] select_alternative { or [guard] select_alternative } [ else sequence_of_statements ] end select;
guard ::= when condition =>
select_alternative ::= accept_alternative | delay_alternative | terminate_alternative
accept_alternative ::= accept_statement [sequence_of_statements]
delay_alternative ::= delay_statement [sequence_of_statements]
terminate_alternative ::= terminate;
Legality Rules
task body Server is Current_Work_Item : Work_Item; begin loop select accept Next_Work_Item(WI : in Work_Item) do Current_Work_Item := WI; end; Process_Work_Item(Current_Work_Item); or accept Shut_Down; exit; -- Premature shut down requested or terminate; -- Normal shutdown at end of scope end select; end loop; end Server;
timed_entry_call ::= select entry_call_alternative or delay_alternative end select;
entry_call_alternative ::= entry_call_statement [sequence_of_statements]Dynamic Semantics
select Controller.Request(Medium)(Some_Item); or delay 45.0; -- controller too busy, try something else end select;
conditional_entry_call ::= select entry_call_alternative else sequence_of_statements end select;Dynamic Semantics
procedure Spin(R : in Resource) is begin loop select R.Seize; return; else null; -- busy waiting end select; end loop; end;
asynchronous_select ::= select triggering_alternative then abort abortable_part end select;
triggering_alternative ::= triggering_statement [sequence_of_statements]
triggering_statement ::= entry_call_statement | delay_statement
abortable_part ::= sequence_of_statementsDynamic Semantics
loop select Terminal.Wait_For_Interrupt; Put_Line("Interrupted"); then abort -- This will be abandoned upon terminal interrupt Put_Line("-> "); Get_Line(Command, Last); Process_Command(Command(1..Last)); end select; end loop;
select delay 5.0; Put_Line("Calculation does not converge"); then abort -- This calculation should finish in 5.0 seconds; -- if not, it is assumed to diverge. Horribly_Complicated_Recursive_Function(X, Y); end select;
abort_statement ::= abort task_name {, task_name};Name Resolution Rules
Bounded (Run-Time) Errors
Dynamic Semantics
Yields the value True when the task denoted by T is callable, and False otherwise; a task is callable unless it is completed or abnormal. The value of this attribute is of the predefined type Boolean.
Yields the value True if the task denoted by T is terminated, and False otherwise. The value of this attribute is of the predefined type Boolean.
Yields the number of calls presently queued on the entry E of the current instance of the unit. The value of this attribute is of the type universal_integer.NOTES
Static Semantics
Erroneous Execution
Examples
task Producer;
task body Producer is Char : Character; begin loop ... -- produce the next character Char Buffer.Write(Char); exit when Char = ASCII.EOT; end loop; end Producer;
task Consumer;
task body Consumer is Char : Character; begin loop Buffer.Read(Char); exit when Char = ASCII.EOT; ... -- consume the character Char end loop; end Consumer;
protected Buffer is entry Read (C : out Character); entry Write(C : in Character); private Pool : String(1 .. 100); Count : Natural := 0; In_Index, Out_Index : Positive := 1; end Buffer;
protected body Buffer is entry Write(C : in Character) when Count < Pool'Length is begin Pool(In_Index) := C; In_Index := (In_Index mod Pool'Length) + 1; Count := Count + 1; end Write;
entry Read(C : out Character) when Count > 0 is begin C := Pool(Out_Index); Out_Index := (Out_Index mod Pool'Length) + 1; Count := Count - 1; end Read; end Buffer;
Go to the first, previous, next, last section, table of contents.