Rationale for Ada 2012
5.4 Interrupt timers and budgets
It will be recalled
that Ada 2005 introduced three packages for monitoring the CPU time used
by tasks. They are a root package
Ada.Execution_Time
plus two child packages thus
Ada.Execution_Time
—
this is the root package and enables the monitoring of execution time
of individual tasks.
Ada.Execution_Time.Timers
—
this provides facilities for defining and enabling timers and for establishing
a handler which is called by the run time system when the execution time
of the task reaches a given value.
Ada.Execution_Time.Group_Budgets
—
this enables several tasks to share a budget and provides means whereby
action can be taken when the budget expires.
The execution time of a task, or CPU time, is the
time spent by the system executing the task and services on its behalf.
CPU times are represented by the private type CPU_Time
declared in the root package Ada.Execution_Time.
However, it was left
implementation defined in Ada 2005 as to how the time spent in interrupts
was to be accounted. The Ada 2005 RM says
It is implementation defined which task, if any,
is charged the execution time that is consumed by interrupt handlers
and run-time services on behalf of the system.
As noted in the AI, a common and simple implementation
will charge the time consumed by the interrupt handlers to the task executing
when the interrupt is generated. This is done under the assumption that
the effect of interrupt handlers on the execution time clocks is negligible
since the interrupt handlers are usually very short pieces of code. However,
in real-time systems that undertake an intensive use of interrupts, this
assumption may not be realistic. For example, Ada 2005 introduced timed
events that can execute handlers in interrupt context. The facility is
convenient and has low overheads, and therefore programmers are tempted
to put more code into these handlers.
It is thus considered important to be able to measure
time spent in interrupts and so facilities to do this are added in Ada
2012.
The root package is
extended by the addition of two Boolean constants, Interrupt_Clocks_Supported
and Separate_Interrupt_Clocks_Supported, and
also a function Clocks_For_Interrupts so in
outline it becomes
with Ada.Task_Identification;
use Ada.Task_Identification;
with Ada.Real_Time;
use Ada.Real_Time;
package Ada.Execution_Time
is
type CPU_Time is private;
...
function Clock(T: Task_Id := Current_Task) return CPU_Time;
...
Interrupt_Clocks_Supported: constant Boolean := implementation-defined;
Separate_Interrupt_Clocks_Supported: constant Boolean := implementation-defined;
function Clocks_For_Interrupts return CPU_Time;
private
... -- not specified by the language
end Ada.Execution_Time;
The constant Interrupt_Clocks_Supported
indicates whether the time spent in interrupts is accounted for separately
from the tasks and then Separate_Interrupt_Clocks_Supported
indicates whether the time is accounted for each interrupt individually.
The new function Clocks_For_Interrupts
returns the CPU_Time used over all interrupts.
It is initialized to zero.
Time accounted for in interrupts is not also accounted
for in individual tasks. In other words there is never any double accounting.
Calling the function Clocks_For_Interrupts
if Interrupt_Clocks_Supported is false raises
Program_Error. Note that the existing function
Clock has a parameter giving the task concerned
whereas Clocks_For_Interrupts does not since
it covers all interrupts.
A new child package
of Ada.Execution_Time is provided for monitoring
the time spent in individual interrupts. Note that this package always
exists even if the Boolean constant Separate_Interrupt_Clocks_Supported
is false. Its specification is
package Ada.Execution_Time.Interrupts
is
function Clock(Interrupt: Ada.Interrupts.Interrupt_Id)
return CPU_Time;
function Supported(Interrupt: Ada.Interrupts.Interrupt_Id)
return Boolean;
end Ada.Execution_Time.Interrupts;
The function Supported
indicates whether the time for a particular interrupt is being monitored.
If it is then Clock returns the accumulated
CPU_Time spent in that interrupt handler (otherwise
it returns zero). However, if the overall constant Separate_Interrupt_Clocks_Supported
is false then calling this function Clock
for any particular interrupt raises Program_Error.
The package Ada.Execution_Time.Timers
is exactly the same in Ada 2012. However, as mentioned earlier, the package
Ada.Execution_Time.Group_Budgets is now defined
to work on a single processor and the type Group_Budget
is modified to include a discriminant giving the CPU concerned.
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by: