Ada Conformity Assessment Authority      Home Conformity Assessment   Test Suite ARGAda Standard
 
Annotated Ada Reference Manual (Ada 2022 with Amendment 1)Legal Information
Contents   Index   References   Search   Previous   Next 

D.14.1 Execution Time Timers

1/3
{AI95-00307-01} {AI05-0299-1} This subclause describes a language-defined package that provides a facility for calling a handler when a task has used a defined amount of CPU time.

Static Semantics

2/2
{AI95-00307-01} The following language-defined library package exists: 
3/5
{AI12-0241-1} {AI12-0302-1} with System;
package Ada.Execution_Time.Timers
   with Nonblocking, Global => in out synchronized is
4/2
   type Timer (T : not null access constant
                       Ada.Task_Identification.Task_Id) is
      tagged limited private;
5/5
{AI12-0241-1}    type Timer_Handler is
      access protected procedure (TM : in out Timer)
      with Nonblocking => False;
6/2
   Min_Handler_Ceiling : constant System.Any_Priority :=
   implementation-defined;
7/2
   procedure Set_Handler (TM      : in out Timer;
                          In_Time : in Time_Span;
                          Handler : in Timer_Handler);
   procedure Set_Handler (TM      : in out Timer;
                          At_Time : in CPU_Time;
                          Handler : in Timer_Handler);
   function Current_Handler (TM : Timer) return Timer_Handler;
   procedure Cancel_Handler (TM        : in out Timer;
                             Cancelled :    out Boolean);
8/2
   function Time_Remaining (TM : Timer) return Time_Span;
9/2
   Timer_Resource_Error : exception;
10/2
private
   ... -- not specified by the language
end Ada.Execution_Time.Timers;
11/2
{AI95-00307-01} The type Timer represents an execution-time event for a single task and is capable of detecting execution-time overruns. The access discriminant T identifies the task concerned. The type Timer needs finalization (see 7.6).
12/2
{AI95-00307-01} An object of type Timer is said to be set if it is associated with a nonnull value of type Timer_Handler and cleared otherwise. All Timer objects are initially cleared.
13/2
{AI95-00307-01} The type Timer_Handler identifies a protected procedure to be executed by the implementation when the timer expires. Such a protected procedure is called a handler.
13.a/2
Discussion: Type Timer is tagged. This makes it possible to share a handler between several events. In simple cases, 'Access can be used to compare the parameter with a specific timer object (this works because a tagged type is a by-reference type). In more complex cases, a type extension of type Timer can be declared; a double type conversion can be used to access the extension data. An example of how this can be done can be found for the similar type Timing_Event, see D.15

Dynamic Semantics

14/2
{AI95-00307-01} When a Timer object is created, or upon the first call of a Set_Handler procedure with the timer as parameter, the resources required to operate an execution-time timer based on the associated execution-time clock are allocated and initialized. If this operation would exceed the available resources, Timer_Resource_Error is raised.
15/3
{AI95-00307-01} {AI05-0264-1} The procedures Set_Handler associate the handler Handler with the timer TM: if Handler is null, the timer is cleared; otherwise, it is set. The first procedure Set_Handler loads the timer TM with an interval specified by the Time_Span parameter. In this mode, the timer TM expires when the execution time of the task identified by TM.T.all has increased by In_Time; if In_Time is less than or equal to zero, the timer expires immediately. The second procedure Set_Handler loads the timer TM with the absolute value specified by At_Time. In this mode, the timer TM expires when the execution time of the task identified by TM.T.all reaches At_Time; if the value of At_Time has already been reached when Set_Handler is called, the timer expires immediately.
15.a/2
Implementation Note: Since an access-to-constant can designate a variable, the Task_Id value designated by the discriminant of a Timer object can be changed after the object is created. Thus, an implementation cannot use the value of the Task_Id other than where this Reference Manual specifies. For instance, the Task_Id should be read when the timer is set, but it should not be used when the timer expires (as it may designate a different task at that point). 
16/2
{AI95-00307-01} A call of a procedure Set_Handler for a timer that is already set replaces the handler and the (absolute or relative) execution time; if Handler is not null, the timer remains set.
17/2
{AI95-00307-01} When a timer expires, the associated handler is executed, passing the timer as parameter. The initial action of the execution of the handler is to clear the event.
18/3
{AI95-00307-01} {AI05-0264-1} The function Current_Handler returns the handler associated with the timer TM if that timer is set; otherwise, it returns null.
19/3
{AI95-00307-01} {AI05-0264-1} The procedure Cancel_Handler clears the timer if it is set. Cancelled is assigned True if the timer was set prior to it being cleared; otherwise, it is assigned False.
20/3
{AI95-00307-01} {AI05-0264-1} The function Time_Remaining returns the execution time interval that remains until the timer TM would expire, if that timer is set; otherwise, it returns Time_Span_Zero.
21/2
{AI95-00307-01} The constant Min_Handler_Ceiling is the minimum ceiling priority required for a protected object with a handler to ensure that no ceiling violation will occur when that handler is invoked.
22/2
{AI95-00307-01} As part of the finalization of an object of type Timer, the timer is cleared.
23/2
{AI95-00307-01} For all the subprograms defined in this package, Tasking_Error is raised if the task identified by TM.T.all has terminated, and Program_Error is raised if the value of TM.T.all is Task_Identification.Null_Task_Id.
23.a/6
To be honest: {AI22-0058-2} One has to check whether TM.T.all is Null_Task_Id before checking whether TM.T.all is terminated; this wording treats these are disjoint conditions. 
24/2
{AI95-00307-01} An exception propagated from a handler invoked as part of the expiration of a timer has no effect.

Erroneous Execution

25/2
{AI95-00307-01} For a call of any of the subprograms defined in this package, if the task identified by TM.T.all no longer exists, the execution of the program is erroneous.

Implementation Requirements

26/2
{AI95-00307-01} For a given Timer object, the implementation shall perform the operations declared in this package atomically with respect to any of these operations on the same Timer object. The replacement of a handler by a call of Set_Handler shall be performed atomically with respect to the execution of the handler.
26.a/2
Reason: This prevents various race conditions. In particular it ensures that if an event occurs when Set_Handler is changing the handler then either the new or old handler is executed in response to the appropriate event. It is never possible for a new handler to be executed in response to an old event 
27/2
{AI95-00307-01} When an object of type Timer is finalized, the system resources used by the timer shall be deallocated.

Implementation Permissions

28/3
{AI95-00307-01} {AI05-0264-1} Implementations may limit the number of timers that can be defined for each task. If this limit is exceeded, then Timer_Resource_Error is raised.
29/2
NOTE   {AI95-00307-01} A Timer_Handler can be associated with several Timer objects.

Extensions to Ada 95

29.a/2
{AI95-00307-01} The package Execution_Time.Timers is new. 

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