CVS difference for ais/ai-00307.txt
--- ais/ai-00307.txt 2003/06/17 21:18:37 1.4
+++ ais/ai-00307.txt 2003/07/03 04:37:47 1.5
@@ -1,6 +1,7 @@
-!standard 9.6 (00) 03-06-10 AI95-00307/03
-!standard D.9 (00)
+!standard D.14 (01) 03-07-02 AI95-00307/04
!class amendment 02-08-28
+!status Amendment 200Y 03-07-02
+!status ARG Approved 12-0-1 03-06-20
!status work item 02-08-28
!status received 02-08-28
@@ -53,12 +54,21 @@
clocks and timers would ease implementation of such flexible
scheduling algorithms in Ada 95.
-Ada 95 does not have any support for execution time monitoring and
-overrun detection. If we want Ada 95 to continue to be the best
-language in the environment of real-time systems, we need to include
-this essential functionality into the language. Java is looking to
-support this feature.
+The Real-Time extensions to POSIX have recently incorporated support for
+execution time monitoring. Real-Time POSIX supports execution time clocks and
+timers that allow an application to monitor the consumption of execution time
+by its tasks, and to set limits for this consumption.
+It could be argued that given that the POSIX standard already defines
+execution time clocks and timers it would not be necessary to have the
+same functionality in the Ada language standard, because the POSIX
+services can be accessed through the appropriate bindings. This is
+true for Ada platforms built on top of POSIX OS implementations, but
+not for bare-machine implementations, like the ones used in embedded
+systems, avionics, etc. For portability purposes it is necessary to
+have this functionality supported in a homogeneous way for all the
+implementations that choose to support it.
@@ -118,28 +128,24 @@
Timer_Error : exception;
- -- may be raised by Timer.Timer_Expired, Timer.Time_Has_Expired,
- -- and Timer.Time_Remaining
Timer_Resource_Error : exception;
- -- may be raised on the declaration of a Timer or calls to
- -- either Arm
... -- not specified by the language
-In this Annex, execution time or cpu time of a given task is defined
-as the time spent by the system executing that task, including the
-time spent executing run-time or system services on behalf of it. The
-mechanism used to measure execution time is implementation
-defined. It is implementation defined to whom will be charged
-the execution time that is consumed by interrupt handlers and run-time
-services on behalf of the system.
+Execution time or cpu time of a given task is defined as the time spent
+by the system executing that task, including the time spent executing
+run-time or system services on behalf of it. The mechanism used to
+measure execution time is implementation defined. 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
The type CPU_Time represents the execution time of a task. The set of
-the type CPU_Time corresponds one-to-one with an implementation-defined
-range of mathematical integers.
+values of the type CPU_Time corresponds one-to-one with an
+implementation-defined range of mathematical integers.
The CPU_Time value I represents the half-open execution-time interval
that starts with I*CPU_Time_Unit and is limited by
@@ -185,56 +191,55 @@
event that triggers the abortion of the instructions of a select
statement with an abortable part.
-When a Timer is created, at a time no later than return from the
-first call of an Arm procedure, the resources required to operate a CPU-time
-timer based on the associated execution-time clock will be allocated
-and initialized. If this operation would exceed the limit of the
-maximum number of timers in the system, the Timer_Resource_Error
-exception is raised. The timer is initialized in the disarmed state.
+When a Timer object is created, or upon the first call to one of its Arm
+procedures, the resources required to operate a CPU-time timer based on
+the associated execution-time clock will be allocated and initialized.
+If this operation would exceed the limit of the maximum number of timers
+in the system, the Timer_Resource_Error exception is raised. The timer
+is initialized in the disarmed state.
-The Timer.Arm protected procedure that takes a Time_Span parameter
+The Arm protected procedure that takes a Time_Span parameter
loads the associated timer with the relative value specified by
Interval and sets it to the armed state. In this state the timer
counts execution time and, when the CPU clock associated with the
timer measures the passage of Interval, it is said to have expired. If
the timer was already armed, it is rearmed.
-The Timer.Arm protected procedure that takes a CPU_Time parameter
+The Arm protected procedure that takes a CPU_Time parameter
loads the associated timer with the absolute value specified by
Abs_Time and sets it to the armed state. In this state the timer
-counts execution time and, when the CPU clock associated with the
+monitors execution time and, when the CPU clock associated with the
timer reaches the value Abs_Time, it is said to have expired. If the
value of Abs_Time had already been reached by the clock at the time of
the call, the timer is set to the armed state and is said to have
expired. If the timer was already armed, it is rearmed.
-The Timer.Disarm protected procedure sets the timer to the disarmed
+The Disarm protected procedure sets the timer to the disarmed
state. In this state no timer expirations occur.
-The Timer.Timer_Expired protected entry suspends the calling task if
-the timer is in the armed state but has not yet expired. The entry is
-allowed to complete when the timer is in the armed state and has
-expired. If the timer is in the disarmed state, the Timer_Error exception
+The Timer_Expired protected entry suspends the calling task until
+the timer expires if the timer is in the armed state; if the timer has
+already expired, then the calling task proceeds. If the timer is in the
+disarmed state, the Timer_Error exception is raised.
-The Timer.Time_Has_Expired protected function returns True if the
+The Time_Has_Expired protected function returns True if the
timer is in the armed state and has expired, and returns False if the
timer is in the armed state but has not yet expired. If the timer is
in the disarmed state, the Timer_Error exception is raised.
-The Timer.Time_Remaining protected function returns, when the timer is
+The Time_Remaining protected function returns, when the timer is
in the armed state, the CPU time interval that remains until the timer
will expire, or a value representing zero if the timer has expired. If
the timer is in the disarmed state, the Timer_Error exception is raised.
-The Timer_Error exception is raised by Timer.Timer_Expired,
-Timer.Timer_Has_Expired, or Timer.Time_Remaining if an attempt is made
+The Timer_Error exception is raised by Timer_Expired,
+Timer_Has_Expired, or Time_Remaining if an attempt is made
to use a timer that is in the disarmed state.
-When an object of type Timer is finalized, the system resources user by
-the timer must be deallocated.
+When an object of type Timer is finalized, the system resources used by
+the timer shall be deallocated.
The range of CPU_Time values shall be sufficient to uniquely represent
the range of execution times from the task start-up to 50 years of
@@ -282,91 +287,12 @@
mechanisms to change the value of CPU_Tick.
-Changes made from previous version include renaming two of the
-components of Timer, making it implementation defined to whom
-system resources are charged, changing time when clock is set
-to zero to be between task creation and start of activation,
-the need to deallocate resources at finalization is moved to
-implementation requirement, exception raised when resources
-not available is Timer_Resource_Error (and this can be raised
-by first call of Arm).
-Need for execution time monitoring functionality
-Traditional real time systems were built (and still are) using cyclic
-executive schedulers. In these systems, if a particular task or
-routine exceeded its budgeted execution time, the system could detect
-the situation. Basically, whenever the minor cycle interrupt came in,
-it could check whether the current action had completed or not. If
-not, that meant an overrun. Unfortunately, in some concurrent
-real-time systems built with priority-based on-line schedulers there
-is no equivalent method to detect and handle execution time
-overruns. This is the case for systems built using the Ada tasking
-model and the associated Real-Time Annex.
-In addition, many flexible real-time scheduling algorithms require the
-capability to measure execution time and be able to perform scheduling
-actions when a certain amount of execution time has been consumed (for
-example, sporadic servers in fixed priority systems, or the constant
-bandwidth server in EDF-scheduled systems). Support for execution time
-clocks and timers is essential to be able to implement such flexible
-In recognition of all these application requirements, the Real-Time
-extensions to POSIX have recently incorporated support for
-them. Real-Time POSIX supports execution time clocks and timers that
-allow an application to monitor the consumption of execution time by
-its tasks, and to set limits for this consumption. The next revision
-of the Ada language should support this functionality in order for
-the language to continue to be the best for programming real-time
-It could be argued that given that the POSIX standard already defines
-execution time clocks and timers it would not be necessary to have the
-same functionality in the Ada language standard, because the POSIX
-services can be accessed through the appropriate bindings. This is
-true for Ada platforms built on top of POSIX OS implementations, but
-not for bare-machine implementations, like the ones used in embedded
-systems, avionics, etc. For portability purposes it is necessary to
-have this functionality supported in a homogeneous way for all the
-implementations that choose to support it.
-The package solution
-One important requirement of any execution-time functionality that may
-be incorporated into the Ada language is that it is implementable on
-top of the POSIX execution-time clocks and timers. Two different ways
-of providing the execution-time monitoring functionality were proposed,
-that satisfied the above requirement. The ARG chose the package
-solution because it does not require changes to the compiler.
-The package proposal defines a new package that includes all the
-operations required to access the execution-time monitoring
-functionality. Some of these operations belong to a protected object
-type that represents execution-time timers. This approach does not
-require modification of the compiler, nor of the run-time system
-(provided that the POSIX execution-time functionality is available),
-but its execution time type is not integrated in the Ada language as a
-Prototype implementations were developed for both of the initial
-proposals, using the MaRTE operating system that provides a POSIX.13
+A prototype implementations was developed for the initial
+proposal, using the MaRTE operating system that provides a POSIX.13
interface and includes execution-time clocks and timers.
-The implementation of the proposal with the execution-time
-functionality integrated into the language requires small
-modifications to the compiler and to the run-time, which are described
-in document . The modifications were implemented in a short period
-of time and should not represent a large effort to current compiler
-The implementation of the package-based proposal is very simple,
+The implementation of the proposal is very simple,
because it does not require modifications to the compiler nor to the
@@ -377,93 +303,49 @@
implementation and it can be seen that it is relatively simple, and
that it does not introduce any significant overhead into the
-The overheads are quite similar in both implementations, and are
+The overhead of the implementation is small.
-The IRTAW group feels that there is a strong need to have the
-execution-time functionality in Ada.
-The IRTAW group is not opposed to having this new functionality
-defined as optional in the Real-Time Systems Annex.
-Discussion of changes requested by the ARG
-A value of the Clock_Id type was used in the first proposal to
-identify each execution-time clock. The ARG questioned its need and
-requested that a Task_Id be used for identifying the execution-time
-clock of a given task. The origin of the Clock_Id type in the original
-proposal was the POSIX API, but it is true that it is not necessary in
-the Ada implementation. In a run-time implementation the (internal)
-clock id would be part of the task control block, and fully
-accessible. In a library-level implementation the (internal) clock_id
-could be obtained via a task attribute, using package
-Ada.Task_Attributes. Although in this case there is some performance
-penalty due to the task attribute, it is implementable.
-Consequently the Clock_Id has been removed from this proposal,
-although it is requested that the performance issue is discussed by
-The ARG pointed out that Time_Of should return a CPU_Time. This was a
-typo in the previous proposal; it is now fixed.
-The ARG also suggests that Time_Of does *not* take a Task_Id
-parameter. The reason for having it was that an implementation could
+The original proposal included Time_Of taking a Task_Id
+parameter. This was included so that an implementation could
choose to have the Task_Id as part of an Execution_Time value, in case
we wished to disallow operations between CPU_Time values of different
-tasks. So if CPU_Time values of different tasks are not comparable and
-we create an exception for disallowing operations among them, we
-should keep the Task_Id parameter; if not, we can delete it. In the
-present proposal it has been deleted.
+tasks. Since we allow operations between CPU_Time values from different tasks,
+the Task_Id is not needed.
-Initial value of the clock
The initial proposal left the initial value of the execution time
-clock of each task unspecified. The ARG requested that the value
-be forced to start at zero. Although in some implementations this
-requirement may imply setting the CPU-Time clock, there is value in
-being able to determine a task's absolute execution time, and
-therefore the proposal has been changed as requested.
+clock of each task unspecified. However, it is valuable to be
+able to determine a task's absolute execution time, and thus the value
+should be forced to start at zero. In some implementations this requirement may
+require saving an initial value of the CPU-Time clock, but this isn't
+an expensive requirement.
Because the execution time value may be set to zero during the task's
activation, the requirement is that the value is set to zero at
some unspecified point between the task creation and the end of the
-Initialize and Finalize
The initial proposal had two protected operations inside the Timer:
Initialize and Finalize. Initialize took a parameter that identified
-the execution time clock to be used. The ARG proposed suppressing
-these operations, and moving the parameter to an access discriminant
-of the protected type or a parameter of the Arm operation, with a
-preference for the later solution.
-The Initialize and Finalize operations can be removed but the
-implication is that in a library implementation of the package on top
-of the POSIX execution-time services, the protected type will have to
-include a component derived from Ada.Finalize.Controlled to ensure
-that appropriate initialization and finalization are made. I have no
-experience with using controlled types, so I cannot comment on whether
-this is a good idea or not. While the issue is discussed, the
-Initialize and Finalize operations have been removed from the
+the execution time clock to be used. These operations appeared unnecessary
+to reviewers; the parameter could be moved to an access discriminant
+of the protected type or a parameter of the Arm operation. The
+reviewers preferred the later solution.
+Without these operations, a library implementation of the package on top
+of the POSIX execution-time services will have to include a component
+derived from Ada.Finalization.Controlled in the protected type to ensure
+that appropriate initialization and finalization are made. This should not
+cause a hardship; restricted runtime implementations may have to resort to
+some "magic", but most implementations will not need extra support. In
+either case, the overhead is small and bounded.
Given that it is forecasted that most implementations of package
Ada.Real_Time.Execution_Time will be made on top of the POSIX
-execution-time services, if the Initialize operation is removed, the
+execution-time services, the
parameter that identifies the clock should be an access discriminant,
and *not* a parameter to Arm. The reason is that in the POSIX API
Execution-Time timers are system objects that require allocation and
@@ -476,18 +358,6 @@
implementing a sporadic server for a given task using a CPU-Time
Timer, but that task itself may use another timer to finish some
particular any-time algorithm that it may be executing.
-In summary, the Initialize and Finalize operations have been deleted
-(with a request that the ARG discusses the issue of using a controlled
-type), and the identification of the task is made as an access
-Relative and absolute Arm
-The initial proposal only had a relative ARM operation. The ARG
-suggested adding also an absolute version. The current proposal
-includes the suggested operation.
Questions? Ask the ACAA Technical Agent