D.11 Asynchronous Task Control
This subclause introduces a language-defined package 
to do asynchronous suspend/resume on tasks. It uses a conceptual held 
priority value to represent the task's held state. 
Static Semantics
The following language-defined 
library package exists: 
with Ada.Task_Identification;
package Ada.Asynchronous_Task_Control 
is
  pragma Preelaborate(Asynchronous_Task_Control);
  
procedure Hold(T : 
in Ada.Task_Identification.Task_Id);
  
procedure Continue(T : 
in Ada.Task_Identification.Task_Id);
  
function Is_Held(T : Ada.Task_Identification.Task_Id)
   
return Boolean;
end Ada.Asynchronous_Task_Control;
 
Dynamic Semantics
After 
the Hold operation has been applied to a task, the task becomes 
held. 
For each processor there is a conceptual 
idle task, which is always 
ready. The base priority of the idle task is below System.Any_Priority'First. 
The 
held priority is a constant of the type Integer whose value 
is below the base priority of the idle task. 
 
  For any priority below System.Any_Priority'First, 
the task dispatching policy is FIFO_Within_Priorities. 
The Hold operation sets the state of T to held. For 
a held task, the active priority is reevaluated as if the base priority 
of the task were the held priority. 
The Continue operation resets the state of T to not-held; 
its active priority is then reevaluated as determined by the task dispatching 
policy associated with its base priority.
The Is_Held function returns True if and only if 
T is in the held state. 
As part of these operations, a check is made that 
the task identified by T is not terminated. 
Tasking_Error 
is raised if the check fails. 
Program_Error is raised 
if the value of T is Null_Task_Id.
 
Erroneous Execution
If any operation in this package 
is called with a parameter T that specifies a task object that no longer 
exists, the execution of the program is erroneous. 
 
Implementation Permissions
An implementation need not support Asynchronous_Task_Control 
if it is infeasible to support it in the target environment. 
38  It is a consequence of the priority 
rules that held tasks cannot be dispatched on any processor in a partition 
(unless they are inheriting priorities) since their priorities are defined 
to be below the priority of any idle task.
39  The effect of calling Get_Priority and 
Set_Priority on a Held task is the same as on any other task.
40  Calling Hold on a held task or Continue 
on a non-held task has no effect.
41  The rules 
affecting queuing are derived from the above rules, in addition to the 
normal priority rules: 
When a held task is on the ready 
queue, its priority is so low as to never reach the top of the queue 
as long as there are other tasks on that queue.
If a task is executing in a protected 
action, inside a rendezvous, or is inheriting priorities from other sources 
(e.g. when activated), it continues to execute until it is no longer 
executing the corresponding construct.
If a task becomes held while waiting 
(as a caller) for a rendezvous to complete, the active priority of the 
accepting task is not affected.
If a task becomes held while waiting 
in a 
selective_accept, 
and an entry call is issued to one of the open entries, the corresponding 
accept_alternative 
executes. When the rendezvous completes, the active priority of the accepting 
task is lowered to the held priority (unless it is still inheriting from 
other sources), and the task does not execute until another Continue.
 
The same holds if the held task is 
the only task on a protected entry queue whose barrier becomes open. 
The corresponding entry body executes.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe