CVS difference for ais/ai-00307.txt

Differences between 1.16 and version 1.17
Log of other versions for file ais/ai-00307.txt

--- ais/ai-00307.txt	2005/06/16 23:47:27	1.16
+++ ais/ai-00307.txt	2005/10/31 05:18:28	1.17
@@ -1,4 +1,4 @@
-!standard D.14 (00)                                  05-05-05  AI95-00307/12
+!standard D.14 (00)                                  05-10-01  AI95-00307/13
 !standard D.14.1 (00)
 !class amendment 02-08-28
 !status Amendment 200Y 04-06-24
@@ -130,8 +130,7 @@
 that starts with I*CPU_Time_Unit and is limited by
 (I+1)*CPU_Time_Unit, where CPU_Time_Unit is an implementation-defined
 real number. For each task, the execution time value is set to zero at
-some unspecified point between the creation of the task and the start
-of the activation of the task.
+the creation of the task.
 
 CPU_Time_First and CPU_Time_Last are the smallest and largest values
 of the CPU_Time type, respectively.
@@ -186,7 +185,7 @@
 
    - An upper bound on the execution-time duration of a clock
      tick. This is a value D such that if t1 and t2 are any execution
-     times of a given task such that t1<t2 and Clock[t1]=Clock[t2]
+     times of a given task such that t1 < t2 and Clock[t1] = Clock[t2]
      then t2-t1 <= D.
 
    - An upper bound on the size of a clock jump. A clock jump is the
@@ -226,7 +225,7 @@
 with System;
 package Ada.Execution_Time.Timers is
 
-   type Timer (T : access Ada.Task_Identification.Task_Id) is
+   type Timer (T : not null access constant Ada.Task_Identification.Task_Id) is
       tagged limited private;
 
    type Timer_Handler is access protected procedure (TM : in out Timer);
@@ -253,7 +252,7 @@
 end Ada.Execution_Time.Timers;
 
 The type Timer represents an execution-time event for a single task and is
-capable of detecting execution time overruns. The access discriminant T
+capable of detecting execution-time overruns. The access discriminant T
 identifies the task concerned. The type Timer needs finalization (see 7.6).
 
 An object of type Timer is said to be *set* if it is associated with a
@@ -283,13 +282,14 @@
 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, when the execution time of the task
-identified by TM.T has increased by In_Time, the timer TM is said to have
-expired. The second procedure Set_Handler loads the timer TM with the absolute
-value specified by At_Time. In this mode, when the execution time of the
-task identified by TM.T reaches At_Time, the timer TM is said to have *expired*;
-if the value of At_Time has already been reached when Set_Handler is called,
-the timer TM is said to be expired.
+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.
 
 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,
@@ -309,13 +309,16 @@
 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.
+
+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.
 
-The constant Min_Handler_Ceiling is the priority value that ensures
-that no ceiling violation would occur, were a handler to be executed.
+As part of the finalization of an object of type Timer, the timer is cleared.
 
 For all the subprograms defined in this package, Tasking_Error
-is raised if the task identified by TM.T has terminated, and Program_Error
-is raised if the value of TM.T is Task_Identification.Null_Task_Id.
+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.
 
 An exception propagated from a handler invoked as part of the expiration of a
 timer has no effect.
@@ -323,7 +326,7 @@
 Erroneous Execution
 
 For a call of any of the subprograms defined in this package, if the task
-identified by TM.T no longer exists, the execution of the program is erroneous.
+identified by TM.T.all no longer exists, the execution of the program is erroneous.
 
 Implementation Requirements
 
@@ -357,7 +360,7 @@
 
 Modern real-time scheduling policies require that applications have
 the ability to measure execution time of tasks, and to detect
-execution time overruns. Two mechanisms were proposed to achieve these
+execution-time overruns. Two mechanisms were proposed to achieve these
 requirements. One was based on a library-level package, and the other
 one was integrated into the Ada 95 language by creating a new Time
 type that could be used in the languages time constructs such as the
@@ -437,7 +440,7 @@
 
 The following is an example of a periodic task that limits its own execution
 time to some predefined amount called WCET (worst-case execution
-time). If an execution time overrun is detected, the task aborts the
+time). If an execution-time overrun is detected, the task aborts the
 remainder of its execution, until the next period.
 
 with Ada.Real_Time, Ada.Execution_Time.Timers, Ada.Task_Identification;
@@ -498,7 +501,7 @@
 Example 2: Lowered task
 -----------------------
 
-In this example, when an execution time overrun is detected the priority
+In this example, when an execution-time overrun is detected the priority
 of the task is lowered to allow other lower priority tasks to
 continue meeting their timing requirements.
 
@@ -604,7 +607,7 @@
                      TS : Time_Span := Time_Span_Zero) @b<return> CPU_Time;
 
 @b<private>
-   ... --  not specified by the language
+   ... --  @i<not specified by the language>
 @b<end> Ada.Execution_Time;>
 
 The @i<execution time> or CPU time of a given task is defined as the time spent by
@@ -622,8 +625,7 @@
 that starts with I*CPU_Time_Unit and is limited by
 (I+1)*CPU_Time_Unit, where CPU_Time_Unit is an implementation-defined
 real number. For each task, the execution time value is set to zero at
-some unspecified point between the creation of the task and the start
-of the activation of the task.
+the creation of the task.
 
 CPU_Time_First and CPU_Time_Last are the smallest and largest values
 of the CPU_Time type, respectively.
@@ -678,13 +680,12 @@
 
 @xbullet<An upper bound on the execution-time duration of a clock
 tick. This is a value D such that if t1 and t2 are any execution
-times of a given task such that t1<t2 and Clock[t1]=Clock[t2]
+times of a given task such that t1 < t2 and Clock[t1] = Clock[t2]
 then t2-t1 <= D.>
 
 @xbullet<An upper bound on the size of a clock jump. A clock jump is the
-difference between two successive distinct values of an execution
--time clock (as observed by calling the Clock function with the
-same Task_Id).>
+difference between two successive distinct values of an execution-time clock
+(as observed by calling the Clock function with the same Task_Id).>
 
 @xbullet<An upper bound on the execution time of a call to the Clock
 function, in processor clock cycles.>
@@ -717,8 +718,8 @@
 @xcode<@b<with> System;
 @b<package> Ada.Execution_Time.Timers @b<is>
 
-   @b<type> Timer (T : @b<access> Ada.Task_Identification.Task_Id) @b<is>
-      @b<limited private>;
+   @b<type> Timer (T : @b<not null access constant> Ada.Task_Identification.Task_Id) @b<is>
+      @b<tagged limited private>;
 
    @b<type> Timer_Handler @b<is>
       @b<access protected procedure> (TM : @b<in out> Timer);
@@ -734,7 +735,7 @@
                           Handler : @b<in> Timer_Handler);
    @b<function> Current_Handler (TM : Timer) @b<return> Timer_Handler;
    @b<procedure> Cancel_Handler (TM        : @b<in out> Timer;
-                             Cancelled : @b<in out> Boolean);
+                             Cancelled :    @b<out> Boolean);
 
    @b<function> Time_Remaining (TM : Timer) @b<return> Time_Span;
 
@@ -745,7 +746,7 @@
 @b<end> Ada.Execution_Time.Timers;>
 
 The type Timer represents an execution-time event for a single task and is
-capable of detecting execution time overruns. The access discriminant T
+capable of detecting execution-time overruns. The access discriminant T
 identifies the task concerned. The type Timer needs finalization (see 7.6).
 
 An object of type Timer is said to be @i<set> if it is associated with a
@@ -759,7 +760,7 @@
 @i<@s8<Dynamic Semantics>>
 
 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 a
+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.
@@ -767,13 +768,14 @@
 The procedures Set_Handler associate the handler Handler with the timer TM; if
 Handler is @b<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, when the execution time of the task
-identified by TM.T has increased by In_Time, the timer TM is said to have
-expired. The second procedure Set_Handler loads the timer TM with the absolute
-value specified by At_Time. In this mode, when the execution time of the
-task identified by TM.T reaches At_Time, the timer TM is said to have
-@i<expired>; if the value of At_Time has already been reached when Set_Handler
-is called, the timer TM is said to be expired.
+Time_Span parameter. In this mode, the timer TM @i<expires> when the execution
+time of the task identified by TM.T.@b<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.@b<all> reaches At_Time; if the value of
+At_Time has already been reached when Set_Handler is called, the timer expires
+immediately.
 
 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
@@ -793,13 +795,16 @@
 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.
+
+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.
 
-The constant Min_Handler_Ceiling is the priority value that ensures
-that no ceiling violation would occur, were a handler to be executed.
+As part of the finalization of an object of type Timer, the timer is cleared.
 
 For all the subprograms defined in this package, Tasking_Error
-is raised if the task identified by TM.T has terminated, and Program_Error
-is raised if the value of TM.T is Task_Identification.Null_Task_Id.
+is raised if the task identified by TM.T.@b<all> has terminated, and Program_Error
+is raised if the value of TM.T.@b<all> is Task_Identification.Null_Task_Id.
 
 An exception propagated from a handler invoked as part of the expiration of a
 timer has no effect.
@@ -826,7 +831,7 @@
 each task. If this limit is exceeded then Timer_Resource_Error is raised.
 
 @xindent<@s9<NOTES@hr
-A Timer_Handler can be associated with several Timer objects.>>
+46  A Timer_Handler can be associated with several Timer objects.>>
 
 !ACATS test
 
@@ -883,6 +888,764 @@
 Also handler is now 'not null'. Text for meaning of
 operators was there al the time; other changes to
 words from minutes made.
+
+****************************************************************
+
+From: John Barnes
+Sent: Tuesday, March 29, 2005  3:08 AM
+
+I have been writing the part of the Rationale on real time and when talking
+about the package Ada.Execution_Time (AI-307) I said
+
+The constants CPU_Time_First and CPU_Time_Last give the range of values of
+CPU_Time. CPU_Tick gives the average interval during which successive calls
+of Clock give the same value and thus is a measure of the accuracy whereas
+CPU_Time_Unit gives the unit of time measured in seconds. We are guaranteed
+that CPU_Tick is no greater than one millisecond and that the range of
+values of CPU_Time is at least 50 years.
+
+Randy is concerned about this. He said
+
+ John notes: "We are guaranteed that CPU_Tick is no greater than one
+millisecond and that the range of values of CPU_Time is at least 50 years."
+Which is interesting because it guarentees that this package cannot be
+implemented on Windows. Well, you could say the tick is 100 nanoseconds,
+because the functions in question return 100 nanoseconds. But the actual
+results have a granularity of 10 milliseconds. (I tried a number of
+different approaches, and concluded that this was all the accuracy that was
+available for "User_Time" and "Kernel_Time".) I wonder if we need to address
+this somehow.
+
+So I put a placeholder in the rat saying "Randy is worried about this"
+
+And  then he said
+
+"And I still am. Sorry, I'm still concerned about the requirements for
+CPU_Time because CPU_Tick is 10 millisecond on Windows (in practice, not in
+definition -- but the definition of CPU_Tick is definitely about practice,
+not the accuracy of API calls). Note that I personally don't care (I don't
+believe Windows is real-time enough to make the claim that it supports
+real-time and thus this Annex), but I know that others have been concerned
+about it in the past. Someone should write a note to the ARG list (I'd like
+to hear Robert's opinion)."
+
+So, can we have any comments please.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, March 30, 2005  7:06 AM
+
+> "And I still am. Sorry, I'm still concerned about the requirements for
+> CPU_Time because CPU_Tick is 10 millisecond on Windows (in practice, not in
+> definition -- but the definition of CPU_Tick is definitely about practice,
+> not the accuracy of API calls). Note that I personally don't care (I don't
+> believe Windows is real-time enough to make the claim that it supports
+> real-time and thus this Annex), but I know that others have been concerned
+> about it in the past. Someone should write a note to the ARG list (I'd like
+> to hear Robert's opinion)."
+
+I agree with the part where Randy says, "I don't believe Windows is
+real-time enough to make the claim that it supports real-time and thus
+this Annex".  Windows compilers can support this package as best they
+can, but not claim conformance.  Seems OK to me.
+
+On the other hand, these kinds of accuracy requirements seem fairly
+silly, because in practise, compiler writers will provide whatever the
+underlying hardware and OS provide.  In that sense, saying things like
+"no greater than one millisecond" doesn't place any requirement on any
+Ada implementation.  We're not (perhaps unfortunately) in a position to
+dictate what hardware and operating systems do, so why the pretense?
+Furthermore, people who *can* support better than one millisecond will
+do so whether the RM says so or not.
+
+Therefore, I wouldn't mind dropping the requirement.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, March 30, 2005  7:01 PM
+
+...
+> I agree with the part where Randy says, "I don't believe Windows is
+> real-time enough to make the claim that it supports real-time and thus
+> this Annex".  Windows compilers can support this package as best they
+> can, but not claim conformance.  Seems OK to me.
+
+This subject has come up in other contexts (esp. on the FRT), and generally
+the conclusion was that it would be Ada, not Windows that would take the
+blame for such a rule. People would have a hard time seeing that Windows
+isn't real-time if the capabilities are in fact good enough for their
+application. And then if Ada won't let them program their application, I'm
+sure that they can find another language to use. That's not the message we
+want to send for Ada!
+
+> On the other hand, these kinds of accuracy requirements seem fairly
+> silly, because in practise, compiler writers will provide whatever the
+> underlying hardware and OS provide.  In that sense, saying things like
+> "no greater than one millisecond" doesn't place any requirement on any
+> Ada implementation.  We're not (perhaps unfortunately) in a position to
+> dictate what hardware and operating systems do, so why the pretense?
+> Furthermore, people who *can* support better than one millisecond will
+> do so whether the RM says so or not.
+>
+> Therefore, I wouldn't mind dropping the requirement.
+
+That seems like a better solution. It's fair to have some requirements on
+the range of CPU_Time (that's not totally forced by the underlying system),
+but requirements on CPU_Tick are silly. That's probably true for
+Real_Time.Tick as well (here, the native Windows tick is also 10
+milliseconds, but there is a high-performance timer that can be used with
+some difficulty to provide better. I don't see any way to safely use the
+high-performance timer for this case, because it is global, not per-thread).
+
+Both Tick and CPU_Tick are required to be documented (in fact, it says so in
+two different places, and it's implied in a third place), so there isn't any
+likely problem of confusion - users can check what they get.
+
+****************************************************************
+
+From: Robert A Duff
+Sent: Wednesday, March 30, 2005  7:43 PM
+
+> This subject has come up in other contexts (esp. on the FRT), and generally
+> the conclusion was that it would be Ada, not Windows that would take the
+> blame for such a rule.
+
+If I recall correctly, some years ago, there was an issue where the Ada
+RM said roughly 32 real-time priority levels are required, and the FRT
+decided that it was OK that Windows has only 7 or so.  I don't remember
+what my opinion was at that time, but right now, I'm inclined to say:
+let's not try to make the Ada standard impose requirements on
+OS/hardware.  And let somebody else (not the Ada RM) decide which
+OS/hardware environments are appropriate for real-time/embedded/whatever
+systems.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Wednesday, March 30, 2005  7:59 PM
+
+Just picked up this trail of emails on CPU_Tick
+
+The definition of the new package follows closely the original
+real-time package - which had these minimum requirements for
+accuracy. In Ada95 I believe it was felt that some minimum
+was needed to 'encourage' implementers to really do real-time
+kernels and not just run Ada on top of ordinary OSs.
+
+Windows can support real-time if the timing requirements are at
+the seconds levels. Other slimmer versions of Windows can do better,
+but I do not know what the size of CPU_Tick is on these (WindowCE
+for example).
+
+For the 'usual' rnage of real-time requirements for embedded systems
+ordinary Windows is not a real-time OS.
+
+I have no real problem with the miniumum requirements been expressed
+in other ways (implementation advice?) - but the message should be
+there somewhere that some level of useful accuracy would be a good idea!
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, March 31, 2005  6:09 AM
+
+...
+> If I recall correctly, some years ago, there was an issue where the Ada
+> RM said roughly 32 real-time priority levels are required, and the FRT
+> decided that it was OK that Windows has only 7 or so.  I don't remember
+> what my opinion was at that time, but right now, I'm inclined to say:
+> let's not try to make the Ada standard impose requirements on
+> OS/hardware.  And let somebody else (not the Ada RM) decide which
+> OS/hardware environments are appropriate for real-time/embedded/whatever
+> systems.
+
+The Ada standard never imposes requirements that cannot be met. That's clear
+in the RM
+
+     6  Contain no variations except those explicitly permitted by this
+        International Standard, or those that are impossible or
+        impractical to avoid given the implementation's execution
+        environment;
+
+That clause (people with good historical knowledge can associate a well
+known Ada 83 AI with this) is there precisely so we do not water down
+requirements just because some OS cannot meet them.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Thursday, March 31, 2005  6:25 AM
+
+A very good point, I had forgotten this global statement
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, March 31, 2005  2:43 PM
+
+> That clause (people with good historical knowledge can associate a well
+> known Ada 83 AI with this) is there precisely so we do not water down
+> requirements just because some OS cannot meet them.
+
+I totally agree.  A Windows implementation of the Real Time Annex should
+document the issues and move on.
+
+However, it does bring up an interesting issue.  At MITRE I worked with
+real-time software as diverse as radars and aircraft landing systems.
+Very few applications--radar of various flavors being the usual
+exceptions--required deadlines shorter than 150 milliseconds.  It may
+seem strange that a fighter jet's fight guidance software uses a 40
+cycle or so cyclic executive--but you can't, and don't want to, move the
+control surfaces even that fast.
+
+Would it be worth having two support levels for the real-time Annex?  I
+don't think so. In practice the division is between "bare metal"
+implementations and those that run on top of an OS, even a real-time
+executive.  There are a lot of features where, in hard-real time systems
+you *have* to know the worst case execution times for all higher
+priority interrupts, and where in (should I call it soft real-time?)
+other systems rough guidance from the OS or compiler implementor is fine.
+
+In practice I think everyone who cares is aware of this divide.  It
+might be nice to put a note in the RT Annex that references 1.1.3(6),
+something like:
+
+"*Note:* Implementations of this Annex may deviate from the
+specifications given here, for example when run under an operating
+system. (See 1.1.3)   In such a situation, deviations from expected
+behavior can be caused by other executing programs and will be difficult
+to determine in advance.  Implementors should document where such
+deviations can be expected.  However, it will not be possible to
+guarantee any real-time performance without an examination of the
+expected environment at execution time."
+
+In other words, "Silly Rabbit! Of course the RM can't tell you anything
+about performance if other high-priority programs are running."  But
+also reminding implementors that documenting such deviations where they
+are understood is very helpful.
+
+****************************************************************
+
+From: Stephen Michell
+Sent: Tuesday, April 5, 2005  7:44 AM
+
+I'm going to agree and disagree with Robert at the same time. The term
+"Real time" has changed in context in the last few years. It is true
+that human-sized devices such as airplanes or tanks or radards need to
+measure real world events in the 1ms-100ms range, but there are now
+whole classes of systems running in the 1microsecond range and even
+sub-microsecond range. The most obvious that comes to mind are
+communications systems.
+
+We are now seeing processors that execute in the range of a few
+megahertz  up to a few gigahertz.. CPU_Tick of less than 1ms makes
+absolulutely no sense, and words about there being 50 years worth of
+CPU_Ticks in 32 bits doesn't do anything. If CPU_Tick even closely
+resembles the rate at which a processor functions then we would need to
+make CPU_Tick at least 1 microsecond  and if an implementation has
+CPU_Tick of 1ns and uses a 32-bit counter then the counter would roll
+over every 2 seconds or 4 seconds, depending upon whether or not you
+used signed integers.
+
+We clearly need to be open to implementations that use 16, 32 or 64 bits
+and have CPU_Tick of a few (say 100) microseconds but we also need be
+able to address the needs of much faster/larger RT systems.
+
+I would suggest that we leave the wording alone. The note should say
+that a CPU_Tick of 1ms gives a 50 yr range before being zeroed, a 1
+microsecond CPU_Tick uses its whole range in 1/2 hour and faster rates
+for CPU_Tick require 64-bit integers to maintain sufficient time for
+real-world applications.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, April 5, 2005  5:17 PM
+
+> I'm going to agree and disagree with Robert at the same time.
+
+I read your msg several times and was unable to detect any respect
+in which you disagreed with me.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, April 5, 2005  7:32 PM
+
+I think I was the Robert in question here.  As far as what Steve said, I
+thought about mentioning communications software, especially military
+radios with frequency hopping as another example of hard real time.
+However, I didn't think it added to the discussion.  There are real-time
+environments where time budgets are short and critical, and where  tasks
+not a part of the main application just won't be run.  There are also
+evironments where real-time behavior is at best an afterthought.  The
+implementor should understand his target market, and not let anything in
+the ARM prevent the implementor from serving that market.
+
+So all I was saying was that some sort of indication in the RM that we
+don't expect hard real-time implementations on top of non-real-time
+operating systems might help.  I know what the RM says, and what it
+intends to imply, but we still get implementors who don't grok
+1.1.3(6).  This just seems to be a good place for a note in the RM, or
+perhaps a "to be honest" in the AARM to say, "Look guys we know that
+there are things you can't do on top of most operating systems, and we
+are not asking you to fake it, just to describe the expected execution
+environment, and where or why it causes problems."
+
+****************************************************************
+
+From: Stephen Michell
+Sent: Tuesday, April 5, 2005  8:34 PM
+
+> I read your msg several times and was unable to detect any respect
+> in which you disagreed with me.
+
+ah, the other Robert. I quoted part of his message. Sorry about the mix-up.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, April 3, 2005 12:08 PM
+
+I've been reading a draft of John Barnes' paper "Rationale for Ada 2005:
+4 Tasking and Real-Time", and I think I've discovered several minor bugs
+in AI's 307, 354, and 357.  I'm looking at version 10 of AI-307 (version
+1.13 in CVS), version 6 of AI-354 (version 1.8 in CVS), and
+AI95-00357/08 (version 1.12 in CVS).
+
+Very nice paper, by the way.
+
+----------------
+
+For Timers, we have:
+
+For each task, the execution time value is set to zero at
+some unspecified point between the creation of the task and the start
+of the activation of the task.
+
+This seems like a bad idea, because you can ask for the time before it's been
+initialized.  I see no benefit to allowing this implementation freedom.  It
+should be zeroed at task creation.  It makes no sense to me that a task's
+priority is set on creation, but it's CPU time is left uninitialized for a
+while.
+
+If you don't agree, then you have to specify what happens if the program *does*
+query an uninitialized time.  Erroneous?  Some implementation-defined value?
+Bounded error (like other uninit vars?).  Better to eliminate the
+tripping hazard.
+
+----
+
+Package Ada.Dispatching.EDF has the same problem: it makes no sense to
+set the priority on task creation, but leave the deadline undefined for
+some unspecified period of time.
+
+----------------
+
+We have:
+
+package Ada.Execution_Time.Timers is
+
+   type Timer (T : access Ada.Task_Identification.Task_ID) is
+      limited private;
+
+The discriminant should be "access constant".
+
+Well, it shouldn't be "access" at all, but that's needed to get around
+the fact that discriminants can't be of a private type -- an annoying
+restriction indeed.  Are we sure we want to expose this language-design
+flaw?  You can't say "X: Timer(T'Identity'Access)".  You have to declare
+an aliased object.  Yuck.  Maybe we should get rid of the discriminant,
+and just have a Set_Task operation.
+
+The discriminant raises other issues.  For example:
+
+    My_Id: aliased Task_Id := ...;
+    My_Timer: Timer(My_Id'Access);
+    ...
+    My_Id := Something_Else;
+
+Does that change the task associated with the timer?  Or is the implementation
+of Timer supposed to make a copy of the Task_Id during initialization?
+Seems to me the AI needs to say, one way or the other.
+
+----------------
+
+It's not clear what happens when a Timer is finalized.  The AI says resources
+are deallocated (which seems like it goes without saying).  But if the Timer is
+Finalized while the task is still running, it seems like we need to say that we
+quit timing it -- the handler won't get called.
+
+I suppose a similar issue arises for Group_Budgets.
+
+----------------
+
+Packages Ada.Execution_Time, Ada.Execution_Time.Timers, and
+Ada.Execution_Time.Group_Budgets all have this sentence:
+
+For all the operations and types defined in this package, Tasking_Error
+is raised if the task identified by T has terminated. Program_Error
+is raised if the value of T is Null_Task_ID.
+
+It doesn't make sense in all cases.
+
+First, I don't understand the "and types" part.  Types don't raise exceptions.
+
+Ada.Execution_Time has only one operation (Clock) that has anything to do with
+tasks.  Split has a parameter called T, but it's not a Task_Id.  The arithmetic
+operations aren't going to raise T_E.  So it should be reworded to talk about
+Clock.
+
+For Timers, there are no parameters called T.  Probably what we want is to
+replace "T" with "TM.T.all"; all the operations have a TM parameter.
+
+I suppose creating a Timer object should also raise T_E if T.all is terminated.
+Maybe that's what the "and types" part was getting at -- but it's not clear.
+
+For Group_Budgets, we need to talk about just those operations that take a
+Task_Id parameter.
+
+----------------
+
+Group_Budgets has:
+
+  function Members(GB: Group_Budget) return Task_Array;
+
+It seems like a conversion the other way would be useful.
+
+----------------
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Sunday, April 3, 2005  7:09 PM
+
+> I've been reading a draft of John Barnes' paper "Rationale for Ada 2005:
+> 4 Tasking and Real-Time", and I think I've discovered several minor bugs
+> in AI's 307, 354, and 357.  I'm looking at version 10 of AI-307 (version
+> 1.13 in CVS), version 6 of AI-354 (version 1.8 in CVS), and
+> AI95-00357/08 (version 1.12 in CVS).
+
+The AIs have been rewritten a lot since they were last posted (by pretty
+much everyone!), so I wouldn't draw too many conclusions from that text...
+
+> Very nice paper, by the way.
+>
+> ----------------
+>
+> For Timers, we have:
+
+You mean execution time. Timers are something else. Execution-time timers
+are something else still. Prepare to be confused. :-)
+
+> For each task, the execution time value is set to zero at
+> some unspecified point between the creation of the task and the start
+> of the activation of the task.
+>
+> This seems like a bad idea, because you can ask for the time before it's been
+> initialized.  I see no benefit to allowing this implementation freedom. It
+> should be zeroed at task creation.  It makes no sense to me that a task's
+> priority is set on creation, but it's CPU time is left uninitialized for a
+> while.
+
+I recall that this question was asked during the deliberations on the AI,
+and I recall being told it was important. I think the issue is that these
+usually come in some way from the kernel (like POSIX or WIndows), and
+setting the zero point in some precise way is impractical. In large part
+because determining the zero value (these things don't start at zero
+naturally) will take some execution time (a kernel call), and we don't want
+to require that overhead at creation. Best let Alan or another real-time
+person explain that further.
+
+> If you don't agree, then you have to specify what happens if the program *does*
+> query an uninitialized time.  Erroneous?  Some implementation-defined value?
+> Bounded error (like other uninit vars?).  Better to eliminate the
+> tripping hazard.
+
+Since these are queried by Task_Id, we already have erroneous cases for
+them. So it doesn't seem to be a major problem. But if you think this is
+worth worrying about, I think Program_Error would be appropriate (surely the
+task knows whether the timer has been initialized). I don't see any reason
+for a bounded error here (either you get the right answer or no answer,
+presuming the Task_Id is good).
+
+> ----
+>
+> Package Ada.Dispatching.EDF has the same problem: it makes no sense to
+> set the priority on task creation, but leave the deadline undefined for
+> some unspecified period of time.
+
+I don't think the deadline is needed until the task is running.
+
+> ----------------
+>
+> We have:
+>
+> package Ada.Execution_Time.Timers is
+>
+>    type Timer (T : access Ada.Task_Identification.Task_ID) is
+>       limited private;
+>
+> The discriminant should be "access constant".
+>
+> Well, it shouldn't be "access" at all, but that's needed to get around
+> the fact that discriminants can't be of a private type -- an annoying
+> restriction indeed.  Are we sure we want to expose this language-design
+> flaw?  You can't say "X: Timer(T'Identity'Access)".  You have to declare
+> an aliased object.  Yuck.  Maybe we should get rid of the discriminant,
+> and just have a Set_Task operation.
+>
+> The discriminant raises other issues.  For example:
+>
+>     My_Id: aliased Task_Id := ...;
+>     My_Timer: Timer(My_Id'Access);
+>     ...
+>     My_Id := Something_Else;
+>
+> Does that change the task associated with the timer?  Or is the
+> implementation
+> of Timer supposed to make a copy of the Task_Id during initialization?
+> Seems to me the AI needs to say, one way or the other.
+
+Ugh.
+
+> ----------------
+>
+> It's not clear what happens when a Timer is finalized.  The AI says resources
+> are deallocated (which seems like it goes without saying).  But if the Timer is
+> Finalized while the task is still running, it seems like we need to say that we
+> quit timing it -- the handler won't get called.
+>
+> I suppose a similar issue arises for Group_Budgets.
+
+This would seem to apply to all three kinds of timers; it would seem to
+apply to them all.
+
+> ----------------
+>
+> Packages Ada.Execution_Time, Ada.Execution_Time.Timers, and
+> Ada.Execution_Time.Group_Budgets all have this sentence:
+>
+> For all the operations and types defined in this package, Tasking_Error
+> is raised if the task identified by T has terminated. Program_Error
+> is raised if the value of T is Null_Task_ID.
+
+This was completely replaced in all of the AIs.
+
+> It doesn't make sense in all cases.
+>
+> First, I don't understand the "and types" part.  Types don't
+> raise exceptions.
+>
+> Ada.Execution_Time has only one operation (Clock) that has anything to do with
+> tasks.  Split has a parameter called T, but it's not a Task_Id. The arithmetic
+> operations aren't going to raise T_E.  So it should be reworded to talk about
+> Clock.
+>
+> For Timers, there are no parameters called T.  Probably what we want is to
+> replace "T" with "TM.T.all"; all the operations have a TM parameter.
+>
+> I suppose creating a Timer object should also raise T_E if T.all is terminated.
+> Maybe that's what the "and types" part was getting at -- but it's not clear.
+>
+> For Group_Budgets, we need to talk about just those operations that take a
+> Task_Id parameter.
+
+I think all of the above issues were already handled. But feel free to
+review the actual AARM text when it is available.
+
+> ----------------
+>
+> Group_Budgets has:
+>
+>   function Members(GB: Group_Budget) return Task_Array;
+>
+> It seems like a conversion the other way would be useful.
+
+What do you mean?
+
+    function What_the_Heck_is_this (T : Task_Array) return Group_Budget;
+
+makes no sense at all, given that budgets are independent objects. And you
+really don't want to be returning budget objects (these are limited, and
+creating new ones makes no sense).
+
+So what *are* you thinking??
+
+> ----------------
+
+General comment: A number of us have been fighting through various issues in
+the remaining parts of the AARM. We've just about completed that. Reviewing
+old versions isn't particularly helpful (you're more likely to catch bugs
+already known than ones not known), and it exhausts those of us who work on
+this every day.
+
+Given that there will be new versions of many of the AIs, of the Amendment,
+and of the AARM no later than next Tuesday, and a meeting will follow that
+quickly, it would be best to save up everyone's energy for those events.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, April 4, 2005  10:51 AM
+
+> I recall that this question was asked during the deliberations on the AI,
+> and I recall being told it was important. I think the issue is that these
+> usually come in some way from the kernel (like POSIX or WIndows), and
+> setting the zero point in some precise way is impractical. In large part
+> because determining the zero value (these things don't start at zero
+> naturally) will take some execution time (a kernel call), and we don't want
+> to require that overhead at creation. Best let Alan or another real-time
+> person explain that further.
+
+I believe that some implementations might want to interact with the
+OS/kernel at the activation point rather than at the creation point.
+(In between would surprise me!)  But I don't see why this
+implementation detail needs to leak into the semantics as a tripping
+hazard.
+
+> > Group_Budgets has:
+> >
+> >   function Members(GB: Group_Budget) return Task_Array;
+> >
+> > It seems like a conversion the other way would be useful.
+>
+> What do you mean?
+>
+>     function What_the_Heck_is_this (T : Task_Array) return Group_Budget;
+
+Something like:
+
+  procedure Add_Tasks
+    (GB: in out Group_Budget; Tasks : Task_Array);
+
+> Given that there will be new versions of many of the AIs, of the Amendment,
+> and of the AARM no later than next Tuesday, and a meeting will follow that
+> quickly, it would be best to save up everyone's energy for those events.
+
+OK.  Pascal, do you want to put these issues on the agenda for the next
+meeting?  If you say my request to change the semantics to "at creation
+time" is out of line (already decided), I still think there are some
+bugs -- holes where the semantics is unclear.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, April 5, 2005  2:37 AM
+
+>We have:
+>
+>package Ada.Execution_Time.Timers is
+>
+>   type Timer (T : access Ada.Task_Identification.Task_ID) is
+>      limited private;
+>
+>The discriminant should be "access constant".
+>
+>Well, it shouldn't be "access" at all, but that's needed to get around
+>the fact that discriminants can't be of a private type -- an annoying
+>restriction indeed.  Are we sure we want to expose this language-design
+>flaw?  You can't say "X: Timer(T'Identity'Access)".  You have to declare
+>an aliased object.  Yuck.  Maybe we should get rid of the discriminant,
+>and just have a Set_Task operation.
+>
+>The discriminant raises other issues.  For example:
+>
+>    My_Id: aliased Task_Id := ...;
+>    My_Timer: Timer(My_Id'Access);
+>    ...
+>    My_Id := Something_Else;
+>
+>Does that change the task associated with the timer?  Or is the implementation
+>of Timer supposed to make a copy of the Task_Id during initialization?
+>Seems to me the AI needs to say, one way or the other.
+
+Maybe it is time to fix all this the right way.  Operations on Task_IDs
+originally went into an Annex for good and sufficient reasons.  But we
+were too dumb to realize that making Task_ID a discrete type and putting
+it in Standard made lots of sense.  Does any implementation use
+something other than a discrete type for Task_ID?  Yeah, I know that it
+is probably an address, but we don't want to make that potential
+conversion visible.  But just having an implementation defined discrete
+type in Standard would recognize the reality that every task does have
+an ID.  (It isn't a distributed cost, since such an ID is needed by the
+task scheduler.) The rest of Task_Identification can be left as a package.
+
+If that is too radical, just make Task_ID a discrete type.  The real
+reason for doing this is that putting tasks in containers is going to be
+a common thing to want to do--at least for some styles of programming.
+Technically having Task_ID as a private type is not going to make that
+impossible, but if it is known to be discrete, AKA word-sized, container
+implementations can be more efficient.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, April 5, 2005  6:58 AM
+
+> Maybe it is time to fix all this the right way.  Operations on Task_IDs
+> originally went into an Annex for good and sufficient reasons.  But we
+> were too dumb to realize that making Task_ID a discrete type and putting
+> it in Standard made lots of sense.  Does any implementation use
+> something other than a discrete type for Task_ID?  Yeah, I know that it
+> is probably an address, but we don't want to make that potential
+> conversion visible.
+
+In AdaMagic, Task_Id is a record containing an access type pointing to a
+TCB, plus a generation count used to detect dangling Ids.  I believe
+that in GNAT it's access-to-TCB.  Not discrete, in either case.
+
+Note that we considered making it a discrete type during Ada 9X.
+In fact, I think we considered requiring/recommending that it
+be dense, so you could index arrays by it.  I guess implementation
+freedom was considered more important; hence a private type.
+
+The "right" fix would be to allow private types as discrims.
+That ain't gonna happen!  It would probably cause all manner
+of language anomalies.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, April 5, 2005  6:54 AM
+
+For what it is worth, our Task-ID is a pair consisting
+of a pointer and a "generation number."  The pointer
+points directly at a "task control block," the generation
+number comes from a field in a TCB that is bumped each time
+the TCB is reused for a different task.  Once storage is
+used as a TCB, it is never reclaimed, but can be reused
+for a different task once the earlier one terminates.
+If the generation number in the task-id doesn't match the one in
+the TCB, then we presume the task has terminated.
+
+This avoids our having to set any kind of pre-set limit
+on the number of tasks, which might be necessary if
+we only had an integral task number, which would presumably
+be an index into an array of TCB pointers.  We could
+change from our current approach if there were compelling
+advantages to some other, but I guess I'm not convinced
+that being a non-private integer type is even a good
+thing, much less a "better" thing.  It is true it
+would allow us to use them as discriminants, but
+that doesn't seem that important overall.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, April 6, 2005  8:14 PM
+
+> OK.  Pascal, do you want to put these issues on the agenda
+> for the next meeting?  If you say my request to change the
+> semantics to "at creation time" is out of line (already
+> decided), I still think there are some bugs -- holes where
+> the semantics is unclear.
+
+Fine with me, but you'll have to write an AI, and do it real quick.
+Please ask Randy for the latest version of the relevant AIs, so that you
+start from the most current wording.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent