CVS difference for ai05s/ai05-0045-1.txt
--- ai05s/ai05-0045-1.txt 2007/07/26 02:57:26 1.3
+++ ai05s/ai05-0045-1.txt 2007/08/07 01:16:17 1.4
@@ -1,4 +1,4 @@
-!standard 9.2(6) 07-06-13 AI05-0045-1/02
+!standard 9.2(6) 07-08-06 AI05-0045-1/03
!class binding interpretation 07-04-04
!status work item 07-04-04
!status received 07-04-02
@@ -35,32 +35,56 @@
Replace 9.2(6) by:
-If a master includes (directly or indirectly) the creation of a task, and it begins
-finalization prior to either initiating the activation of the new task or returning
-the task to a caller as part or coextension of a return object, the new task is never
-activated and becomes terminated.
+If a return statement is left such that the return object is not returned
+to the caller, any task that was created as part or coextension of the
+return object immediately becomes terminated and is never activated
+[irregardless of where it would have been activated]. Otherwise, if a master
+that directly encloses the point where the activation of a task T would be
+initiated begins finalization before the activation of T is initiated, T
+becomes terminated and is never activated.
+
+ AARM Notes: The first case can happen with an exception being raised in a return
+ statement, by an exit or goto from an extended_return_statement, or by a
+ return statement being aborted. Any tasks created for the return object of
+ such a return statement are never activated.
+
+ The second case can only happen if the activation point of T is not reached
+ due to an exception being raised or the task being aborted. Note that this is
+ exclusive; if the master is being finalized, we're already past the activation
+ point and since Ada doesn't have any restart semantics, we can never get there.
+ End AARM Notes.
-AARM Note: A master could indirectly include the creation of a task if the task is
-returned to it from a function call. This rule covers such tasks that aren't activated.
+[Editor's note: The square brackets here mark redundant text.]
-A created task might not be activated because of an exception being raised, because
-of an abort, or because of a transfer of control out of an extended_return_statement.
-
!discussion
-What is important here is what happens if the master of unactivated tasks is finalized
-(as then we would need to wait for them). We don't care why the tasks were never
-activated. Thus, the original wording of 9.2(6) says too much. It also has a race
-condition, in that if the task is aborted when it reaches the activation point but
-before the tasks actually are activated, this rule doesn't seem to apply.
+What is important here is what happens if the master that directly encloses
+the activation point of any unactivated tasks is finalized. We don't care why the
+tasks were never activated or where they were created. Thus, the original wording
+of 9.2(6) says too much. It also has a race condition, in that if the task is
+aborted when it reaches the activation point but before the tasks actually are
+activated, this rule doesn't seem to apply.
The wording also is not clear about precisely when the tasks become terminated. The tasks
being terminated on creation would meet the requirements of this rule. Thus, the value
of T'Terminated is not well-defined for such tasks. That seems bad.
-Because of all of these reasons, we've rewritten the rule in terms of finalization
-rather than "reaching the point of activation".
+Because of all of these reasons, we've rewritten the rule in terms of finalization of
+a master rather than "reaching the point of activation".
+While the most critical point is when the master of the tasks begins to finalize (because
+we would need to wait for the unactivated tasks at that point), writing the rule
+that way could cause unactivated tasks to hang around in a limbo state for a long time.
+(Consider an allocator for an access-to-task that is declared at library level; the
+master is that of the environment task.) Thus we talk about the master of that encloses
+the activation point of the task.
+
+We need a special rule for a return statement which is completed without returning to the
+caller (a "failed" return), because the activation point of those tasks may be executed
+if the function executes a second return statement successfully. In that case, the tasks
+created by the failed return should never be activated, while the second set created by
+the later successful return do need to be activated. This doesn't fit cleanly into
+the model.
!corrigendum 9.2(6/2)
@@ -69,10 +93,13 @@
initiate the activations (due to an abort or the raising of an exception), the
newly created tasks become terminated and are never activated.
@dby
-If a master includes (directly or indirectly) the creation of a task, and it begins
-finalization prior to either initiating the activation of the new task or returning
-the task to a caller as part or coextension of a return object, the new task is never
-activated and becomes terminated.
+If a return statement is left such that the return object is not returned
+to the caller, any task that was created as part or coextension of the
+return object immediately becomes terminated and is never activated
+irregardless of where it would have been activated. Otherwise, if a master
+that directly encloses the point where the activation of a task T would be
+initiated begins finalization before the activation of T is initiated, T
+becomes terminated and is never activated.
!ACATS test
@@ -275,7 +302,6 @@
From: Randy Brukardt
Date: Monday, April 2, 2007 9:40 PM
-
> This might be ok, but it makes me nervous because it doesn't quite
> correspond to how most implementations would want to implement this.
@@ -352,6 +378,830 @@
So I think you've convinced me that I'm on the right track. It certainly is simpler than
talking about executing the point of task activation. I'll write it up this way and then
the full ARG can tear it to bits...
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Wednesday, July 18, 2007 8:02 PM
+
+The wording proposed in Paris for this AI is to replace 9.2(6) with the
+following:
+
+If a master includes (directly or indirectly) the creation of a task, and it
+begins finalization prior to either initiating the activation of the
+new task or returning the task to a caller as part or coextension of
+a return object, the new task is never activated and becomes terminated.
+
+However, I don't think this wording works; it has the same problem with the
+example Steve gave at the meeting as my original proposal.
+
+Steve's example was:
+
+procedure P is
+ type Ref is access T_has_Task;
+ Ptr : Ref;
+ task Child;
+ task body Child is
+ begin
+ Ptr := new T_has_Task;
+ end Child;
+begin
+ null;
+end P;
+
+The allocator is clearly "indirectly" included in the master of P (as it is
+the master of Child). If that master begins finalization during the
+execution of the allocator (and before the activation of the task), the task
+would be "brutally killed" (as Pascal put it in his notes on the minutes).
+But Child is still running and presumably is expecting the task to be
+working.
+
+The reason that the "indirectly" was added was so that the outer master that
+is handled the return object is also one that "includes the creation of a
+task". But this is clearly too broad. I think we need to drop the
+"indirectly" and address the case of return objects explicitly.
+
+Something like:
+
+If a master directly includes the creation of a task, and it begins
+finalization prior to either initiating the activation of the new task or
+returning the task to a caller as part or coextension of a return object,
+the new task is never activated and becomes terminated. For the purposes of
+this rule, a return object which is returned normally is deemed to have been
+directly included in the master surrounding the point of call (see 3.10.2).
+
+I'm not very thrilled with this wording, as it introduces a special case.
+OTOH, a return object is the only case where the master of an object changes
+after it is created, so it seems likely that it is the only special case
+that need be handled.
+
+Tucker *always* has a better idea about wording (even if it is wrong, as in
+the wording proposed at the meeting), so I'm hoping that he has a better
+idea that actually works. (The rest of you can make suggestions as well, of
+course.)
+
+****************************************************************
+
+From: Tucker Taft
+Date: Wednesday, July 18, 2007 9:08 PM
+
+I'm not convinced there is a problem, because I don't believe
+the execution of a subtask is *included* in the execution of
+the parent task. We could be more explicit by clearly limiting
+this to masters within the creating task, if we really felt
+there was a danger of confusion. Hence:
+
+ If a task T1 creates a task T2, and if a master within task T1
+ that includes (directly or indirectly) the creation of the task T2
+ begins finalization prior to either initiating
+ the activation of task T2 or returning task T2 to a
+ caller as part or coextension of a return object, task T2
+ is never activated and becomes terminated.
+
+But as indicated above, I think the Paris wording is fine, because
+of the use of the phraseology "master includes," which really means
+"the execution of the master construct includes." I don't think
+we have in the past implied that a task "includes" the execution of its
+subtasks.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Wednesday, July 18, 2007 10:00 PM
+
+> If a task T1 creates a task T2, and if a master within task T1
+> that includes (directly or indirectly) the creation of the task T2
+> begins finalization prior to either initiating
+> the activation of task T2 or returning task T2 to a
+> caller as part or coextension of a return object, task T2
+> is never activated and becomes terminated.
+
+This looks fine to me (and yes, there is a danger, in fact certainty, of
+confusion).
+
+> But as indicated above, I think the Paris wording is fine, because
+> of the use of the phraseology "master includes," which really means
+> "the execution of the master construct includes."
+
+This is news to me. If we meant "the execution of the master construct
+includes", we should say so, because otherwise I would expect that what is
+"included" in a master to be a statically determined thing (as opposed to
+the nesting of masters, which is dynamic). Ada doesn't allow declarations to
+occur dynamically!
+
+> I don't think
+> we have in the past implied that a task "includes" the execution of its
+> subtasks.
+
+But in that case, I have no idea what "indirect" means in this context. If a
+master M1 includes the creation of a master M2, then it surely "indirectly"
+includes the execution of its subtasks. How could it not? The master created
+the task! Indeed, just about the only thing that *could* be indirectly
+included would be a subtask, because everything else is directly included
+(assuming that masters are transitive, which is something we've generally
+assumed elsewhere).
+
+My understanding was that the "(directly or indirectly)" was added to ensure
+that transitivity was obvious. But it has exactly the opposite effect,
+making it seem likely that unrelated stuff is included. I think an AARM note
+explaining precisely what was meant would be more useful, because it can use
+as many words as needed to be clear (a parenthetical remark cannot do that).
+
+When it comes to accessibility and masters, *everything* is confusing! We
+need to use wording that is absolutely crystal-clear and leaves as little to
+the imagination as possible. And I don't want people to have to understand
+every nuance of accessibility and masters before they can figure out how
+tasks terminate in the usual cases.
+
+****************************************************************
+
+From: Robert A. Duff
+Date: Thursday, July 19, 2007 3:03 PM
+
+> > I'm not convinced there is a problem, because I don't believe
+> > the execution of a subtask is *included* in the execution of
+> > the parent task.
+
+I agree with Tucker about what "included" means (or should mean).
+Perhaps the notion of "dynamically enclosing (of one execution by another)"
+defined in 11.4(2) would help here? The definition makes it clear that only
+one task is involved.
+
+****************************************************************
+
+From: Tucker Taft
+Date: Thursday, July 19, 2007 3:25 PM
+
+I don't disagree with your [Randy's - ED] point about being clear,
+but it is important to macro-expand the term "master"
+to "the execution of a master construct" every place
+you see it. A master is an *execution*. That is
+pretty well established in 7.6.1(3/2) in the definition
+of the term. Of course, informal discussion often
+treats "master" as a category of syntactic constructs,
+but that of course is wrong... ;-)
+
+****************************************************************
+
+From: Robert I. Eachus
+Date: Sunday, July 22, 2007 8:48 PM
+
+> If a task T1 creates a task T2, and if a master within task T1
+> that includes (directly or indirectly) the creation of the task T2
+> begins finalization prior to either initiating
+> the activation of task T2 or returning task T2 to a
+> caller as part or coextension of a return object, task T2
+> is never activated and becomes terminated.
+
+Hmm. I think the source of the confusion here is mentioning task T1.
+We all know that the conditions being discussed can only happen if
+there something above the master which becomes terminated. But that has
+nothing to do with the conditions addressed. We have an
+uninterruptable last wishes situation:
+
+If a master that includes (directly or indirectly) the creation of a
+task begins finalization prior to either initiating the activation of
+the task or returning the task to a caller as part or coextension of a
+return object, the task is never activated and becomes terminated.
+
+So leaving the scope of the master has to change the status of the
+created task to terminated. But editing it down like this makes it
+clear that it is either redundant or wrong! Currently 9.1(4) says: "For
+tasks created by the evaluation of an allocator, the activations are
+initiated as the last step of evaluating the allocator, after completing
+any initialization for the object created by the allocator, and prior to
+returning the new access value." This separation into two steps means
+that the case where you have an allocator that creates more than one
+task can result in one task becoming activated and immediately aborting
+the parent before it can finish activating all the tasks. Worse, what
+happens when a created task creates another task as part of its
+activation? I could, but, won't, write a test.
+
+If we say instead:
+
+If a master that includes (directly or indirectly) the creation of a
+task begins finalization prior to either initiating the activation of
+the task or returning the task to a caller as part or coextension of a
+return object, the task becomes terminated.
+
+There are no orphans around, and the order of creation of tasks in an
+allocator is immaterial. Does this allow, in the nested tasks case, for
+a situation where the new task has observable effects during elaboration
+of the task body, then fails, taking out the parent? Sure. But I don't
+think the intent is to change that. As I see it, all that we really
+need to do is insure that tasks don't outlive their master.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Monday, July 23, 2007 11:34 PM
+
+> > If a task T1 creates a task T2, and if a master within task T1
+> > that includes (directly or indirectly) the creation of the task T2
+> > begins finalization prior to either initiating
+> > the activation of task T2 or returning task T2 to a
+> > caller as part or coextension of a return object, task T2
+> > is never activated and becomes terminated.
+>
+> Hmm. I think the source of the confusion here is mentioning task T1.
+
+No, that was Tucker's attempt to *fix* the confusion. The problem is whether
+"includes indirectly" includes nested tasks. (We don't want it to.) Tucker
+claims that it does not, but has no language wording to prove that; I claim
+it is unclear and thus we need to fix it.
+
+> We all know that the conditions being discussed can only happen if
+> there something above the master which becomes terminated. But that has
+> nothing to do with the conditions addressed. We have an
+> uninterruptable last wishes situation:
+>
+> If a master that includes (directly or indirectly) the creation of a
+> task begins finalization prior to either initiating the activation of
+> the task or returning the task to a caller as part or coextension of a
+> return object, the task is never activated and becomes terminated.
+
+This wording has exactly the same meaning as the other one, and it makes the
+"includes indirectly" problem much worse, because in the previous wording,
+it is clear that the finalization of a master of a task other than the one
+that created the task is irrelevant; that is not clear here.
+
+> So leaving the scope of the master has to change the status of the
+> created task to terminated. But editing it down like this makes it
+> clear that it is either redundant or wrong! Currently 9.1(4) says: "For
+> tasks created by the evaluation of an allocator, the activations are
+> initiated as the last step of evaluating the allocator, after completing
+> any initialization for the object created by the allocator, and prior to
+> returning the new access value." This separation into two steps means
+> that the case where you have an allocator that creates more than one
+> task can result in one task becoming activated and immediately aborting
+> the parent before it can finish activating all the tasks.
+
+This is well-defined: aborting a task causes any masters it has to be
+finalized. So it is clearly covered by the wording.
+
+> Worse, what happens when a created task creates another task as part of
+its
+> activation? I could, but, won't, write a test.
+
+What's worse about that? Again, we're only interested in the master of the
+task that created the task; and that will always be finalized. The inner
+task will be terminated before the outer one, and that is as it should be.
+
+> If we say instead:
+>
+> If a master that includes (directly or indirectly) the creation of a
+> task begins finalization prior to either initiating the activation of
+> the task or returning the task to a caller as part or coextension of a
+> return object, the task becomes terminated.
+
+All you've done here is eliminate some wording which makes it clear that a
+task can't be both terminated and pending actuvation, Essentially, you've
+introduced a race condition.
+
+> There are no orphans around, and the order of creation of tasks in an
+> allocator is immaterial. Does this allow, in the nested tasks case, for
+> a situation where the new task has observable effects during elaboration
+> of the task body, then fails, taking out the parent? Sure. But I don't
+> think the intent is to change that. As I see it, all that we really
+> need to do is insure that tasks don't outlive their master.
+
+There are no orphans in any proposed wording (or the existing wording, for
+that matter), since every created task belongs to a master, and all masters
+are finalized. So there is no way for an orphan to be created. I think
+you're making a problem where none existed.
+
+****************************************************************
+
+From: Robert I. Eachus
+Date: Tuesday, July 24, 2007 11:41 AM
+
+>No, that was Tucker's attempt to *fix* the confusion. The problem is whether
+>"includes indirectly" includes nested tasks. (We don't want it to.) Tucker
+>claims that it does not, but has no language wording to prove that; I claim
+>it is unclear and thus we need to fix it.
+
+Ah, I was assuming that you wanted to include created tasks that have
+not yet been activated. As I read the intent, tasks that are not yet
+activated are affected, and running tasks are only affected if their
+master is aborted. (They become abnormal, then must terminate before
+the master is completes finalization.) That was the distinction I was
+trying to make. In that case, you have to split the hairs I was
+splitting about when a task gets activated. My point was that in the
+case of record designated by an access value containing more than one
+task with say library unit masters, it matters whether all are activated
+simultaneously, or if some but not all tasks can be activated before the
+abort.
+
+>>If a master that includes (directly or indirectly) the creation of a
+>>task begins finalization prior to either initiating the activation of
+>>the task or returning the task to a caller as part or coextension of a
+>>return object, the task is never activated and becomes terminated.
+>
+>This wording has exactly the same meaning as the other one, and it makes the
+>"includes indirectly" problem much worse, because in the previous wording,
+>it is clear that the finalization of a master of a task other than the one
+>that created the task is irrelevant; that is not clear here.
+
+Right, it is that never "activated and becomes terminated" that concerns
+me. If the master of the tasks is left as part of the termination, no
+problem. But if the master of the created tasks is not finalized along
+with the task creating the new tasks, the question of indivisibility vs.
+some order matters.
+
+>>So leaving the scope of the master has to change the status of the
+>>created task to terminated. But editing it down like this makes it
+>>clear that it is either redundant or wrong! Currently 9.1(4) says: "For
+>>tasks created by the evaluation of an allocator, the activations are
+>>initiated as the last step of evaluating the allocator, after completing
+>>any initialization for the object created by the allocator, and prior to
+>>returning the new access value." This separation into two steps means
+>>that the case where you have an allocator that creates more than one
+>>task can result in one task becoming activated and immediately aborting
+>>the parent before it can finish activating all the tasks.
+>
+>This is well-defined: aborting a task causes any masters it has to be
+>finalized. So it is clearly covered by the wording.
+
+Yes, my wording here probably should have used Tuck's task
+designations. Even then it is not clear. Let me try again. Task T1
+creates two tasks by means of an allocator. Task T1 is the master, or
+includes the master of task T2. Task T3 and possibly more. are also
+created by the allocator, but have other masters. For simplicity assume
+library level masters.
+
+>>Worse, what happens when a created task creates another task as part
+>>of its activation? I could, but, won't, write a test.
+>
+>What's worse about that? Again, we're only interested in the master of the
+>task that created the task; and that will always be finalized. The inner
+>task will be terminated before the outer one, and that is as it should be.
+
+Maybe I should write the example. T1 creates T2 and is directly or
+indirectly its master. Task T2 as part of its activation creates T5 and
+T6 library level masters. T6 raises Tasking_Error as part of, or
+immediately subsequent to its activation. If there are no handlers
+intervening this will terminate T2 then T1. But what about T5? Can T5
+have completed activation before T6? If so since it has a library level
+master, it stays alive and can have observable effects. I've always
+assumed that 9.2 allowed such tasks to survive termination of their
+creator, and that some such tasks and not others might have been
+activated, if one of a set of task activations raises Tasking_Error in
+its creator. See AARM 9.2(5.a). Tasking_Error is only raised once, even
+if several tasks being activated together fail. This is where I get the
+"some order" semantics. You don't have to elaborate the
+declarative_parts of the various task_bodies sequentially, but if you
+don't you have to collect all the Tasking_Errors raised and pass on just
+one. See AARM 9.2(5.b). Yes, these are very much not normative text,
+but I don't think it is wise to change the implied model.
+
+>>If we say instead:
+>>
+>>If a master that includes (directly or indirectly) the creation of a
+>>task begins finalization prior to either initiating the activation of
+>>the task or returning the task to a caller as part or coextension of a
+>>return object, the task becomes terminated.
+>
+>All you've done here is eliminate some wording which makes it clear that a
+>task can't be both terminated and pending activation, Essentially, you've
+>introduced a race condition.
+
+No, I'm trying to preserve a race condition! As far as any
+implemetation is concerned, they can choose not to have tasks in such as
+state. A task can become terminated prior to or in the middle of
+activation. In particular, if an implementation decides to allow
+parallel activation, it is possible for two tasks each to see the other
+as pending activation or terminated. The same thing can occur if the
+parent or master is aborted--if a task is being elaborated on one
+processor while another is causing it to become abnormal, the task whose
+task body is being elaborated can be in both states simultaneously.
+
+ From an RM perspective, we have a group of tasks being activated
+simultaneously from the point of the task doing the activation, but not
+from other points of view. In particular if a task creates other tasks
+by allocators during activation, they can look at their creator. (Or for
+that matter, their siblings, if an object contains several tasks.) They
+cannot see the creating task as both callable and terminated, but which
+they see in certain programs should be implementation dependent.
+
+>>There are no orphans around, and the order of creation of tasks in an
+>>allocator is immaterial. Does this allow, in the nested tasks case, for
+>>a situation where the new task has observable effects during elaboration
+>>of the task body, then fails, taking out the parent? Sure. But I don't
+>>think the intent is to change that. As I see it, all that we really
+>>need to do is insure that tasks don't outlive their master.
+>
+>There are no orphans in any proposed wording (or the existing wording, for
+>that matter), since every created task belongs to a master, and all masters
+>are finalized. So there is no way for an orphan to be created. I think
+>you're making a problem where none existed.
+
+I think we are using slightly different definitions of orphans, but it
+doesn't matter in that we agree that there are none. I was thinking of
+tasks being activated when their creator, not master, is aborted. Either
+the task becomes activated before its creator is terminated, or it dies
+before the creator is left. In either case, it is safe for the
+implementation to refer to data owned by the creator during activation.
+Whether implemetations do that or copy any necessary data to the new TCB
+before activation is an implementation detail.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Tuesday, July 24, 2007 1:39 PM
+
+...
+> Right, it is that never "activated and becomes terminated" that concerns
+> me.
+
+That's Ada 83 wording (9.3(4)) and thus it has always been part of the
+model.
+
+> If the master of the tasks is left as part of the termination, no
+> problem. But if the master of the created tasks is not finalized along
+> with the task creating the new tasks, the question of indivisibility vs.
+> some order matters.
+
+Activation is indivisible in the sense that a task either has started
+activation or it has not. It's not possible for it to be between those two
+states. And, for the purposes of this rule, it is only the start of
+activation that matters, not the completion of it.
+
+...
+> Maybe I should write the example. T1 creates T2 and is directly or
+> indirectly its master. Task T2 as part of its activation creates T5 and
+> T6 library level masters.
+
+I assume via allocators, because otherwise the master is the same as it's
+parent.
+
+> T6 raises Tasking_Error as part of, or
+> immediately subsequent to its activation. If there are no handlers
+> intervening this will terminate T2 then T1. But what about T5? Can T5
+> have completed activation before T6?
+
+Completed activation is not interesting for the purposes of this rule; it is
+only the start that matters.
+
+> If so since it has a library level
+> master, it stays alive and can have observable effects.
+
+Yes, of course.
+
+> I've always
+> assumed that 9.2 allowed such tasks to survive termination of their
+> creator, and that some such tasks and not others might have been
+> activated, if one of a set of task activations raises Tasking_Error in
+> its creator. See AARM 9.2(5.a). Tasking_Error is only raised once, even
+> if several tasks being activated together fail. This is where I get the
+> "some order" semantics. You don't have to elaborate the
+> declarative_parts of the various task_bodies sequentially, but if you
+> don't you have to collect all the Tasking_Errors raised and pass on just
+> one. See AARM 9.2(5.b). Yes, these are very much not normative text,
+> but I don't think it is wise to change the implied model.
+
+Nothing about this rule changes this model. After all, it only applies when
+the master of the tasks is finalized. At that point, it is not possible for
+a task to be activated (that always happens within the master that owns the
+task).
+
+If task T5 has begun activation, then this rule does not apply to it (it
+says "prior to initiating the activation" after all). The other (unchanged)
+termination rules will apply to that task. OTOH, if T5 has not begun
+activation, then it never can (because the activation point has to have been
+aborted/left before the master has started finalization), and this rule
+applies. And it says that the task can never be activated and becomes
+terminated.
+
+> >>If we say instead:
+> >>
+> >>If a master that includes (directly or indirectly) the creation of a
+> >>task begins finalization prior to either initiating the activation of
+> >>the task or returning the task to a caller as part or coextension of a
+> >>return object, the task becomes terminated.
+> >
+> >All you've done here is eliminate some wording which makes it clear that a
+> >task can't be both terminated and pending activation, Essentially, you've
+> >introduced a race condition.
+>
+> No, I'm trying to preserve a race condition! As far as any
+> implemetation is concerned, they can choose not to have tasks in such as
+> state. A task can become terminated prior to or in the middle of
+> activation. In particular, if an implementation decides to allow
+> parallel activation, it is possible for two tasks each to see the other
+> as pending activation or terminated.
+
+No, that isn't possible, because a task can only become terminated after it
+has completed all finalization. That can't be "in the middle of activation";
+the activation has to have finished (or failed) in order for that to happen.
+
+> The same thing can occur if the
+> parent or master is aborted--if a task is being elaborated on one
+> processor while another is causing it to become abnormal, the task whose
+> task body is being elaborated can be in both states simultaneously.
+
+No, that would be a broken implementation of Ada. The terminated state is
+exclusive of all other possible states of a task. You can get to it from
+many other states, but it cannot be in any other state.
+
+> From an RM perspective, we have a group of tasks being activated
+> simultaneously from the point of the task doing the activation, but not
+> from other points of view. In particular if a task creates other tasks
+> by allocators during activation, they can look at their creator. (Or for
+> that matter, their siblings, if an object contains several tasks.) They
+> cannot see the creating task as both callable and terminated, but which
+> they see in certain programs should be implementation dependent.
+
+Now you're saying that it can't be in two states at once. Of course, the
+exact state you are in will depend on the runtime, the execution speed of
+the processor, etc. But it can't be in more than one state.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Saturday, July 24, 2007 12:00 AM
+
+Tucker Taft wrote:
+
+> If a task T1 creates a task T2, and if a master within task T1
+> that includes (directly or indirectly) the creation of the task T2
+> begins finalization prior to either initiating
+> the activation of task T2 or returning task T2 to a
+> caller as part or coextension of a return object, task T2
+> is never activated and becomes terminated.
+
+This wording has been bothering me for several days based on something
+Robert Eachus said,
+and I've finally figured out what's the issue is.
+
+I can't convince myself that it must be the case that the same master
+encloses the creation and the activation point of a task (even in the
+absence of a return statement). There are so many things that create masters
+now that it is hard to reason about them, and it is trivial to add some to
+declarations (via expressions or Initialize routines).
+
+In any case, I don't think we really need to talk about the creation the
+task; that's not very relevant as it is only the activation point that
+matters. If we don't do that, then we can eliminate two issues with this
+wording: the "indirectly" business, and any concern about which masters are
+involved (or not involved).
+
+The wording could be something like:
+
+"If a master that directly encloses the point where the activation of a task
+T would be initiated begins finalization before the activation of T is
+initiated, T becomes terminated and is never activated."
+
+This wording is a bit redundant (perhaps someone has a idea to improve it),
+but it's simpler because we've gotten rid of "indirect"; there is no need to
+worry about normal returns here because such a return just changes the
+location of activation (and this wording *only* worries about that
+location).
+
+We do have one problem though; a return statement which is exited before the
+return still might actually execute the activation point - but we don't want
+its tasks activated - ever. So we need a special case for that. And we
+probably need an AARM note. (Square brackets mean redundant in the wording
+proposal below.)
+
+"If a return statement is left such that the return object is not returned
+to the caller, any task that was created as part or coextension of the
+return object immediately becomes terminated and is never activated
+[irregardless of where it would have been activated]. Otherwise, if a master
+that directly encloses the point where the activation of a task T would be
+initiated begins finalization before the activation of T is initiated, T
+becomes terminated and is never activated.
+
+ AARM Notes: The first case can happen with an exception being raised in a return
+ statement, by an exit or goto from an extended_return_statement, or by a
+ return statement being aborted. Any tasks created for the return object of
+ such a return statement are never activated.
+
+ The second case can only happen if the activation point of T is not reached
+ due to an exception being raised or the task being aborted. Note that this is
+ exclusive; if the master is being finalized, we're already past the activation
+ point and since Ada doesn't have any restart semantics, we can never get there."
+
+I think this is better, although the wording of the first sentence is
+somewhat awkward (I'd rather not talk about task creation, but I can't think
+of any other way to put it). And it's annoying to put the rare case first.
+But there's no dependence on "indirect" masters; everything is defined in
+terms of a single, specific master for each task. For that reason, we can't
+get in trouble if the definition of masters is tweaked and we don't have to
+worry about what master created a task.
+
+Thoughts? Clever ways to simply this wording?
+
+****************************************************************
+
+From: Robert I. Eachus
+Date: Wednesday, August 1, 2007 8:14 AM
+
+> This wording has been bothering me for several days based on something
+> Robert Eachus said, and I've finally figured out what's the issue is.
+
+I knew we were talking past each other. I think I now know what you
+were focusing on.
+
+> I can't convince myself that it must be the case that the same master
+> encloses the creation and the activation point of a task (even in the
+> absence of a return statement). There are so many things that create masters
+> now that it is hard to reason about them, and it is trivial to add some to
+> declarations (via expressions or Initialize routines).
+
+I'm convinced that all activations are enclosed in the master, or the
+master is at library level. The problem is that you can have nested
+activations, and when that happens, specifying the master in a sentence
+is tough. From an implementation point of view, it is easy. The master
+is deterimined at compile time, by the static nesting of the appropriate
+declaration. Of course, that declaration can be a task declaration, an
+object declaration, or an access type declaration..
+
+> In any case, I don't think we really need to talk about the creation the
+> task; that's not very relevant as it is only the activation point that
+> matters. If we don't do that, then we can eliminate two issues with this
+> wording: the "indirectly" business, and any concern about which
+> masters are
+> involved (or not involved).
+>
+> The wording could be something like:
+>
+> "If a master that directly encloses the point where the activation of
+> a task
+> T would be initiated begins finalization before the activation of T is
+> initiated, T becomes terminated and is never activated."
+
+Good. This is what I was really trying to explain. I hope you mean what
+I was asking for though. Activation is an indivisible operation from
+the point of view of the activating task: A group of tasks all get
+initiated at a particular point in the execution.
+
+However, that covers a multitude of execution during the elaboration of
+the newly created tasks. IF the elaboration of one task causes the
+task enclosing it and several others to become completed, is it possible
+that some tasks were activated and others never activated? This new
+wording seems to avoid discussing that case.
+
+> We do have one problem though; a return statement which is exited before the
+> return still might actually execute the activation point - but we don't want
+> its tasks activated - ever. So we need a special case for that. And we
+> probably need an AARM note. (Square brackets mean redundant in the wording
+> proposal below.)
+>
+> "If a return statement is left such that the return object is not returned
+> to the caller, any task that was created as part or coextension of the
+> return object immediately becomes terminated and is never activated
+> [irregardless of where it would have been activated]. Otherwise, if a master
+> that directly encloses the point where the activation of a task T would be
+> initiated begins finalization before the activation of T is initiated, T
+> becomes terminated and is never activated.
+>
+I don't think you need the first part of this paragraph given the last
+sentence in (Ada 2007) 9.2(4/2):
+
+"For tasks that are part or coextensions of a single object that is not
+a stand-alone object, activations are initiated after completing any
+initialization of the outermost object enclosing these tasks, prior to
+performing any other operation on the outermost object. In particular,
+for tasks that are part or coextensions of the object created by the
+evaluation of an allocator
+<http://www.adaic.org/standards/05rm/html/RM-4-8.html#S0129>, the
+activations are initiated as the last step of evaluating the allocator
+<http://www.adaic.org/standards/05rm/html/RM-4-8.html#S0129>, prior to
+returning the new access value. For tasks that are part or coextensions
+of an object that is the result of a function call, the activations are
+not initiated until after the function returns."
+
+But the otherwise clause in Randy's proposal again avoids the problem
+case I was worrying about. What happens if one of the created tasks
+raises an exception during its elaboration? It has already started
+activation, and it is possible that several other tasks have as well.
+The task raising the exception becomes a failed task, no problem there.
+But what about the other tasks which may be initiated at the same point
+in the containing task? My read has always been that some tasks may have
+(started and) completed elaboration, and such tasks will not wait for
+all other tasks in the group to complete activation before executing the
+task body. They exist and are active.
+
+Later when one of the tasks in the group fails, these tasks will become
+abnormal, then completed etc. It is easy to create a task that takes
+say an hour to elaborate before failing. A (legitimate) implementation
+might do sequential elaboration in that case. But AFAIK, it is not
+required.
+
+Programmers for today's supercomputers want parallel elaboration of
+tasks. Forget the programming language used for a minute. Distributing
+code to thousands of CPU cores is not easy, and the subject of lots of
+study. We don't want to put artificial barriers in their way. My
+understanding is that in Ada, the activation point is a synchronization
+point for the creator and all the created tasks, but the completion of
+activation is a one way syncronization point. When all the created
+tasks are activated successfully the creating task can proceed. This
+may not seem simple, but in a message passing environment it is about as
+simple as possible. The master task sends out messages telling each
+processor where in the code to begin execution. If that task gets back
+a failure message, it sends out termination messages to all the created
+tasks, otherwise when it gets back the right number of successes, it can
+continue execution. The one to many messages create the most (wall
+clock) overhead, and you want to have just one. If Ada tasks required
+an additional synchronization at the end of activation, that would
+double the number of messages required as part of program initiation.
+More important, it would add a second one to many message.
+
+I wrote another post trying to make what I see more visible. Microsoft
+ate it--I left it open overnight without saving a copy, you would have
+thought I would have learned that lesson by now. :-( Anyway, I was
+still trying to get the explanation right:
+
+When one or more tasks are activated, the activating task, or main
+program, sees activation of a set of tasks as an indivisible operation,
+which may complete successfully, or raise Tasking_Error.
+
+The activated task however, each has its own view of time, or progress
+through the program code. Activation of a task at execution time may
+overlap with the activation of other tasks. We had that fight decades
+ago. And if no one remembers the problems caused by sequential
+activation, don't bother to dig out 1982 (I think) papers. The real
+killer was that multiple simultaneous activations could occur in some
+cases anyway, and in any case sequential elaboration had its problems.
+Eventually, it just seemed silly to make an array of task objects a
+special case. (Or a different case from an array of access to task
+values. ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Thursday, August 2, 2007 10:12 AM
+
+...
+> However, that covers a multitude of execution during the elaboration of
+> the newly created tasks. IF the elaboration of one task causes the
+> task enclosing it and several others to become completed, is it possible
+> that some tasks were activated and others never activated? This new
+> wording seems to avoid discussing that case.
+
+That's purely intentional; I don't want this wording to specify something
+that was left unspecified in Ada in the past. I certainly think that an
+abort of the activator task could leave some of the activating tasks
+unactivated, and the wording needs to cover that case without requiring it.
+
+...
+
+> I don't think you need the first part of this paragraph given the last
+> sentence in (Ada 2007) 9.2(4/2):
+>
+> "For tasks that are part or coextensions of a single object that is not
+> a stand-alone object, activations are initiated after completing any
+> initialization of the outermost object enclosing these tasks, prior to
+> performing any other operation on the outermost object. In particular,
+> for tasks that are part or coextensions of the object created by the
+> evaluation of an allocator
+> <http://www.adaic.org/standards/05rm/html/RM-4-8.html#S0129>, the
+> activations are initiated as the last step of evaluating the allocator
+> <http://www.adaic.org/standards/05rm/html/RM-4-8.html#S0129>, prior to
+> returning the new access value. For tasks that are part or coextensions
+> of an object that is the result of a function call, the activations are
+> not initiated until after the function returns."
+
+This text defines where the activations task place. But in this specific
+case (a return statement that is completed (by a transfer of control or an
+abort) but that does *not* return to the caller), we *never* want to
+activate the tasks, *even* if the activation point is later executed (as it
+will be if the transfer of control remains inside of the function and goes
+to a point that also executes a return statement).
+
+That's because the second return statement will also create tasks in the
+return object, and it is that second set that we want activated, not the
+first.
+
+> But the otherwise clause in Randy's proposal again avoids the problem
+> case I was worrying about.
+
+I surely hope so; there is no reason to specify anything, and leaving it
+unspecified is just fine. What's the problem with that? It's been
+unspecified since the beginning of (Ada) time.
+
+In any case, the only thing this wording considers indivisible is the
+*start* of activation of a task. Once the activation has started, this
+wording does not apply. Period. And this is only relevant for the task
+itself, what the activator is doing is mostly irrelevent (which is why I
+prefer this wording to Tucker's). The only thing that matters is that the
+activator cannot both be starting the activation of a task and finalizing
+something at the same time; because finalization is exclusive of other
+activities of a task (which necessarily includes activations). In
+particular, an aborted task cannot finalize anything until it has stopped
+any other activities -- but there is nothing new about that (that's why
+"immediate abort" is so hard to define).
+
+****************************************************************
+
+From: Robert I. Eachus
+Date: Friday, August 3, 2007 7:05 PM
+
+Totally agree. I originally got torqued out of shape by wording that
+involved that implied that activation of a group of tasks was an
+indivisible act. Of course, it looks that way from the point of view
+of the task doing the activations. It isn't and hasn't been for the
+other tasks, and the wording may not have intended to imply that.
****************************************************************
Questions? Ask the ACAA Technical Agent