Next: , Previous: D.14.1, Up: D.14


D.14.2 Group Execution Time Budgets

1/2
{00354AI95−00354−01} This clause describes a language−defined package to assign execution time budgets to groups of tasks.

Static Semantics

2/2
{00354AI95−00354−01} The following language−defined library package exists:

3/2

     with System;
     package Ada.Execution_Time.Group_Budgets is

4/2

       type Group_Budget is tagged limited private;

5/2

       type Group_Budget_Handler is access
            protected procedure (GB in out Group_Budget);

6/2

       type Task_Array is array (Positive range <>) of
                                       Ada.Task_Identification.Task_Id;

7/2

       Min_Handler_Ceiling constant System.Any_Priority :=
         implementation−defined;

8/2

       procedure Add_Task (GB in out Group_Budget;
                            in Ada.Task_Identification.Task_Id);
       procedure Remove_Task (GB: in out Group_Budget;
                               in Ada.Task_Identification.Task_Id);
       function Is_Member (GB Group_Budget;
                           Ada.Task_Identification.Task_Id) return Boolean;
       function Is_A_Group_Member
          (T Ada.Task_Identification.Task_Id) return Boolean;
       function Members (GB Group_Budget) return Task_Array;

9/2

       procedure Replenish (GB in out Group_Budget; To in Time_Span);
       procedure Add (GB in out Group_Budget; Interval in Time_Span);
       function Budget_Has_Expired (GB Group_Budget) return Boolean;
       function Budget_Remaining (GB Group_Budget) return Time_Span;

10/2

       procedure Set_Handler (GB      in out Group_Budget;
                              Handler in Group_Budget_Handler);
       function Current_Handler (GB Group_Budget)
          return Group_Budget_Handler;
       procedure Cancel_Handler (GB        in out Group_Budget;
                                 Cancelled out Boolean);

11/2

       Group_Budget_Error exception;

12/2

     private
         −−  not specified by the language
     end Ada.Execution_Time.Group_Budgets;

13/2
{00354AI95−00354−01} The type Group_Budget represents an execution time budget to be used by a group of tasks. The type Group_Budget needs finalization (see 7.6). A task can belong to at most one group. Tasks of any priority can be added to a group.

14/2
{00354AI95−00354−01} An object of type Group_Budget has an associated nonnegative value of type Time_Span known as its budget, which is initially Time_Span_Zero. The type Group_Budget_Handler identifies a protected procedure to be executed by the implementation when the budget is exhausted, that is, reaches zero. Such a protected procedure is called a handler.{budget} {exhaust (a budget)} {handler (group budget) [partial]} 15/2
{00354AI95−00354−01} An object of type Group_Budget also includes a handler, which is a value of type Group_Budget_Handler. The handler of the object is said to be set if it is not null and cleared otherwise. The handler of all Group_Budget objects is initially cleared. {set (group budget object) [partial]} {clear (group budget object) [partial]} 15.a/2

Discussion: Type Group_Budget 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 group budget object (this works because a tagged type is a by−reference type). In more complex cases, a type extension of type Group_Budget 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

16/2
{00354AI95−00354−01} The procedure Add_Task adds the task identified by T to the group GB; if that task is already a member of some other group, Group_Budget_Error is raised.

17/2
{00354AI95−00354−01} The procedure Remove_Task removes the task identified by T from the group GB; if that task is not a member of the group GB, Group_Budget_Error is raised. After successful execution of this procedure, the task is no longer a member of any group.

18/2
{00354AI95−00354−01} The function Is_Member returns True if the task identified by T is a member of the group GB; otherwise it return False.

19/2
{00354AI95−00354−01} The function Is_A_Group_Member returns True if the task identified by T is a member of some group; otherwise it returns False.

20/2
{00354AI95−00354−01} The function Members returns an array of values of type Task_Identification.Task_Id identifying the members of the group GB. The order of the components of the array is unspecified.

21/2
{00354AI95−00354−01} The procedure Replenish loads the group budget GB with To as the Time_Span value. The exception Group_Budget_Error is raised if the Time_Span value To is non−positive. Any execution of any member of the group of tasks results in the budget counting down, unless exhausted. When the budget becomes exhausted (reaches Time_Span_Zero), the associated handler is executed if the handler of group budget GB is set. Nevertheless, the tasks continue to execute.

22/2
{00354AI95−00354−01} The procedure Add modifies the budget of the group GB. A positive value for Interval increases the budget. A negative value for Interval reduces the budget, but never below Time_Span_Zero. A zero value for Interval has no effect. A call of procedure Add that results in the value of the budget going to Time_Span_Zero causes the associated handler to be executed if the handler of the group budget GB is set.

23/2
{00354AI95−00354−01} The function Budget_Has_Expired returns True if the budget of group GB is exhausted (equal to Time_Span_Zero); otherwise it returns False.

24/2
{00354AI95−00354−01} The function Budget_Remaining returns the remaining budget for the group GB. If the budget is exhausted it returns Time_Span_Zero. This is the minimum value for a budget.

25/2
{00354AI95−00354−01} The procedure Set_Handler associates the handler Handler with the Group_Budget GB; if Handler is null, the handler of Group_Budget is cleared, otherwise it is set.

26/2
{00354AI95−00354−01} A call of Set_Handler for a Group_Budget that already has a handler set replaces the handler; if Handler is not null, the handler for Group_Budget remains set.

27/2
{00354AI95−00354−01} The function Current_Handler returns the handler associated with the group budget GB if the handler for that group budget is set; otherwise it returns null.

28/2
{00354AI95−00354−01} The procedure Cancel_Handler clears the handler for the group budget if it is set. Cancelled is assigned True if the handler for the group budget was set prior to it being cleared; otherwise it is assigned False.

29/2
{00354AI95−00354−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.

30/2
{00354AI95−00354−01} The precision of the accounting of task execution time to a Group_Budget is the same as that defined for execution−time clocks from the parent package.

31/2
{00354AI95−00354−01} As part of the finalization of an object of type Group_Budget all member tasks are removed from the group identified by that object.

32/2
{00354AI95−00354−01} If a task is a member of a Group_Budget when it terminates then as part of the finalization of the task it is removed from the group.

33/2
{00354AI95−00354−01} For all the operations defined in this package, Tasking_Error is raised if the task identified by T has terminated, and Program_Error is raised if the value of T is Task_Identification.Null_Task_Id.

34/2
{00354AI95−00354−01} An exception propagated from a handler invoked when the budget of a group of tasks becomes exhausted has no effect.

Erroneous Execution

35/2
{00354AI95−00354−01} {erroneous execution (cause) [partial]} For a call of any of the subprograms defined in this package, if the task identified by T no longer exists, the execution of the program is erroneous.

Implementation Requirements

36/2
{00354AI95−00354−01} For a given Group_Budget object, the implementation shall perform the operations declared in this package atomically with respect to any of these operations on the same Group_Budget object. The replacement of a handler, by a call of Set_Handler, shall be performed atomically with respect to the execution of the handler.

36.a/2

Reason: This prevents various race conditions. In particular it ensures that if the budget is exhausted when Set_Handler is changing the handler then either the new or old handler is executed and the exhausting event is not lost.

     NOTES

37/2

43  {00354AI95−00354−01} Clearing or setting of the handler of a group budget does not change the current value of the budget. Exhaustion or loading of a budget does not change whether the handler of the group budget is set or cleared.

38/2

44  {00354AI95−00354−01} A Group_Budget_Handler can be associated with several Group_Budget objects.
Extensions to Ada 95

38.a/2

{00354AI95−00354−01} {extensions to Ada 95} The package Execution_Time.Group_Budgets is new.