* Delayed deallocation of non-terminated task in Gnat?
@ 2011-08-30 13:22 Marc C
2011-08-30 15:20 ` Dmitry A. Kazakov
` (2 more replies)
0 siblings, 3 replies; 21+ messages in thread
From: Marc C @ 2011-08-30 13:22 UTC (permalink / raw)
Saw this pop up in AdaCore's Developer Center notices:
>[GNAT] Automatic deallocation of task upon termination
>
>Monday August 29, 2011
>
>If Unchecked_Deallocation is called on a non-terminated task (which was previously a no-op),
>the task is now marked to be freed automatically when it terminates.
[http://www.adacore.com/2011/08/29/NF-65-H911-007-gnat/]
This *looks* to me like one could dynamically allocate a task instance
and then immediately free it with an instantiation of
Unchecked_Deallocation, yet the task would continue to function
normally until it terminates.
This seems rather a stretch to me, is there more to this than this
brief summary lets on?
Marc A. Criley
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 13:22 Delayed deallocation of non-terminated task in Gnat? Marc C @ 2011-08-30 15:20 ` Dmitry A. Kazakov 2011-08-31 18:12 ` Robert A Duff 2011-08-30 15:38 ` Adam Beneschan 2011-08-31 18:08 ` Robert A Duff 2 siblings, 1 reply; 21+ messages in thread From: Dmitry A. Kazakov @ 2011-08-30 15:20 UTC (permalink / raw) On Tue, 30 Aug 2011 06:22:43 -0700 (PDT), Marc C wrote: > Saw this pop up in AdaCore's Developer Center notices: > >>[GNAT] Automatic deallocation of task upon termination >> >>Monday August 29, 2011 >> >>If Unchecked_Deallocation is called on a non-terminated task (which was previously a no-op), >>the task is now marked to be freed automatically when it terminates. > > [http://www.adacore.com/2011/08/29/NF-65-H911-007-gnat/] > > This *looks* to me like one could dynamically allocate a task instance > and then immediately free it with an instantiation of > Unchecked_Deallocation, yet the task would continue to function > normally until it terminates. Does it mean that Unchecked_Deallocation won't wait for the task to terminate? That would be surprising. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 15:20 ` Dmitry A. Kazakov @ 2011-08-31 18:12 ` Robert A Duff 2011-08-31 19:23 ` Dmitry A. Kazakov 2011-08-31 20:25 ` J-P. Rosen 0 siblings, 2 replies; 21+ messages in thread From: Robert A Duff @ 2011-08-31 18:12 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > Does it mean that Unchecked_Deallocation won't wait for the task to > terminate? That would be surprising. U_D does not wait for tasks to terminate. That's always been the case. I consider it a flaw in Ada that there's no general-purpose way to block waiting for the termination of a task, or a group of tasks. I'm not sure U_D should be that feature, though, because then it would only work for access-to-task(s). - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 18:12 ` Robert A Duff @ 2011-08-31 19:23 ` Dmitry A. Kazakov 2011-08-31 20:58 ` Robert A Duff 2011-08-31 20:25 ` J-P. Rosen 1 sibling, 1 reply; 21+ messages in thread From: Dmitry A. Kazakov @ 2011-08-31 19:23 UTC (permalink / raw) On Wed, 31 Aug 2011 14:12:26 -0400, Robert A Duff wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > >> Does it mean that Unchecked_Deallocation won't wait for the task to >> terminate? That would be surprising. > > U_D does not wait for tasks to terminate. That's always been > the case. > > I consider it a flaw in Ada that there's no general-purpose > way to block waiting for the termination of a task, Yes. If there exist terminate alternative, it must have a corresponding entry. E.g. T'Terminate could denote the terminate entry of the task T. The semantics of the rendezvous to T'Terminate is obvious, upon completion the callee is terminated. It would be simple to introduce, IMO. Also the terminate alternative should allow a handled sequence of statements, e.g. select ... or terminate [do ... end terminate]; ... end select; > or a group of tasks. There is no rendezvous to multiple tasks or calls to multiple entry points (of several protected objects). It could be useful but the semantics is unclear. > I'm not sure U_D should be that feature, though, > because then it would only work for access-to-task(s). It certainly should. The behavior of an object may not depend on the way it was allocated. Since deallocation of a task on the stack is effectively blocking, so its deallocation using Unchecked_Deallocation should be. I see no use in a non-blocking Unchecked_Deallocation. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 19:23 ` Dmitry A. Kazakov @ 2011-08-31 20:58 ` Robert A Duff 2011-08-31 21:16 ` Jeffrey Carter 0 siblings, 1 reply; 21+ messages in thread From: Robert A Duff @ 2011-08-31 20:58 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes: > Yes. If there exist terminate alternative, it must have a corresponding > entry. E.g. > > T'Terminate > > could denote the terminate entry of the task T. The semantics of the > rendezvous to T'Terminate is obvious, upon completion the callee is > terminated. It would be simple to introduce, IMO. Simple to introduce from a semantics point of view, and useful, but rather tricky to implement, for the same reasons that the feature we're discussing (avoiding the storage leak) is tricky. If a task itself notices that it is about to terminate, and therefore frees resources (the task control block, the task stack), it is running while it's doing that stuff, and it's tricky to make sure it doesn't use those resources after they're freed. E.g., the free wanted to defer/undefer aborts, which involves touching the task control block, which is being freed! We figured out how to do it, and it wasn't a lot of code, but it was very subtle code. >> or a group of tasks. > > There is no rendezvous to multiple tasks or calls to multiple entry points > (of several protected objects). That was proposed for Ada 9X. >... It could be useful but the semantics is > unclear. As I recall, there was both "and" and "or" semantics. So in the context of termination, that would give you "wait until all these tasks are terminated", and "wait until one of these tasks is terminated (and tell me which one)". >> I'm not sure U_D should be that feature, though, >> because then it would only work for access-to-task(s). > > It certainly should. The behavior of an object may not depend on the way it > was allocated. Since deallocation of a task on the stack is effectively > blocking, so its deallocation using Unchecked_Deallocation should be. I see > no use in a non-blocking Unchecked_Deallocation. Maybe you're right, I'm not sure. I think it does make sense to fire up a task, and have it get freed on termination, with no particular other task waiting for that termination. The U_D you want, that waits for termination, can be written in terms of the mythical "await termination" primitive we discussed above, and the existing Ada U_D that does not wait. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 20:58 ` Robert A Duff @ 2011-08-31 21:16 ` Jeffrey Carter 0 siblings, 0 replies; 21+ messages in thread From: Jeffrey Carter @ 2011-08-31 21:16 UTC (permalink / raw) On 08/31/2011 01:58 PM, Robert A Duff wrote: > "Dmitry A. Kazakov"<mailbox@dmitry-kazakov.de> writes: > >> There is no rendezvous to multiple tasks or calls to multiple entry points >> (of several protected objects). > > That was proposed for Ada 9X. One can do select Entry_Call_1; then abort Entry_Call_2; end select; and select Entry_Call_1; then abort select Entry_Call_2; then abort Entry_Call_3; end select; end select; and so on forever, as far as I can tell. This has the effect of waiting for one of multiple entry calls. -- Jeff Carter "You a big nose have it." Never Give a Sucker an Even Break 107 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 18:12 ` Robert A Duff 2011-08-31 19:23 ` Dmitry A. Kazakov @ 2011-08-31 20:25 ` J-P. Rosen 2011-08-31 21:09 ` Robert A Duff 1 sibling, 1 reply; 21+ messages in thread From: J-P. Rosen @ 2011-08-31 20:25 UTC (permalink / raw) Le 31/08/2011 20:12, Robert A Duff a �crit : > I consider it a flaw in Ada that there's no general-purpose > way to block waiting for the termination of a task. > With some cooperation of the other task... Declare in the waited task an entry (Wait_For_Terminate) which is never accepted. The waiting task calls the entry, and gets Tasking_Error when the waited task terminates (for whatever reason). -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Adalog a d�m�nag� / Adalog has moved: 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 20:25 ` J-P. Rosen @ 2011-08-31 21:09 ` Robert A Duff 2011-08-31 21:53 ` Simon Wright 0 siblings, 1 reply; 21+ messages in thread From: Robert A Duff @ 2011-08-31 21:09 UTC (permalink / raw) "J-P. Rosen" <rosen@adalog.fr> writes: > Le 31/08/2011 20:12, Robert A Duff a �crit : >> I consider it a flaw in Ada that there's no general-purpose >> way to block waiting for the termination of a task. >> > With some cooperation of the other task... > > Declare in the waited task an entry (Wait_For_Terminate) which is never > accepted. The waiting task calls the entry, and gets Tasking_Error when > the waited task terminates (for whatever reason). We thought of that while implementing the feature that started this thread. Unfortunately, it doesn't quite work. The Tasking_Error is raised when the task is completed, so at the time T_E is handled, the other task could still be going about its business doing finalization. And even if there's no user-level finalization involved, there's still some stuff going on in the run-time system between completion and termination. So there's an inherent race condition here. What I claim is missing from Ada (and is hard to implement) is a feature that blocks a task until some other task(s) is/are really and truly terminated, and won't execute a single 'nother instruction. You can loop, checking 'Terminated, with a delay. But the delay is guaranteed to be either too long or too short -- most likely both. The feature we're talking about was implemented because there was such a loop, and it was causing an AdaCore customer's program (with thousands of dynamically allocated tasks) to take half an hour. After implementing this feature, and removing the loop-with-delay, it took a few seconds. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 21:09 ` Robert A Duff @ 2011-08-31 21:53 ` Simon Wright 0 siblings, 0 replies; 21+ messages in thread From: Simon Wright @ 2011-08-31 21:53 UTC (permalink / raw) Robert A Duff <bobduff@shell01.TheWorld.com> writes: > You can loop, checking 'Terminated, with a delay. But the delay is > guaranteed to be either too long or too short -- most likely both. > The feature we're talking about was implemented because there was such > a loop, and it was causing an AdaCore customer's program (with > thousands of dynamically allocated tasks) to take half an hour. After > implementing this feature, and removing the loop-with-delay, it took a > few seconds. We couldn't afford to wait, so once we discovered the leak we arranged that all tasks to be deleted were aborted and placed on a special list; a low-priority task did the loop-with-delay-until-terminated and then the U_D. generic type Task_Type (<>) is limited private; -- The class's task type (T). type Task_Type_P is access Task_Type; -- The class's pointer-to-task (T_P). with function Is_Terminated (It : Task_Type_P) return Boolean; -- We can't say that Task_Type is actually a task, so we can't use -- 'Identity. package ColdFrame.Task_Deletion_G is procedure Free (It : Task_Type_P); -- Puts It on the queue of tasks to be freed. private (a) all the instantiations and calls of this code were autogenerated, so the developer pain was minimised; (b) we didn't have many task deletions (mainly on network disconnects). ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 13:22 Delayed deallocation of non-terminated task in Gnat? Marc C 2011-08-30 15:20 ` Dmitry A. Kazakov @ 2011-08-30 15:38 ` Adam Beneschan 2011-08-30 16:42 ` Dmitry A. Kazakov 2011-08-31 16:39 ` Adam Beneschan 2011-08-31 18:08 ` Robert A Duff 2 siblings, 2 replies; 21+ messages in thread From: Adam Beneschan @ 2011-08-30 15:38 UTC (permalink / raw) On Aug 30, 6:22 am, Marc C <mc.provisio...@gmail.com> wrote: > Saw this pop up in AdaCore's Developer Center notices: > > >[GNAT] Automatic deallocation of task upon termination > > >Monday August 29, 2011 > > >If Unchecked_Deallocation is called on a non-terminated task (which was previously a no-op), > >the task is now marked to be freed automatically when it terminates. > > [http://www.adacore.com/2011/08/29/NF-65-H911-007-gnat/] > > This *looks* to me like one could dynamically allocate a task instance > and then immediately free it with an instantiation of > Unchecked_Deallocation, yet the task would continue to function > normally until it terminates. > > This seems rather a stretch to me, is there more to this than this > brief summary lets on? I think this is right---the task continues to function until it terminates. The only way to get a task to stop executing before it completes is to abort it (via an abort statement, or other semantics that cause an abort---see 9.8). An Unchecked_Deallocation instance finalizes the task object, but the semantics of finalization don't involve aborting. I'm having a bit of difficulty figuring out from the RM what the exact semantics of finalizing an unterminated task object are, but I'm pretty sure that aborting the task is not one of them. (Note that this applies only to tasks without discriminants. If the task has discriminants, freeing it is an error---13.11.2(11ff).) -- Adam -- Adam ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 15:38 ` Adam Beneschan @ 2011-08-30 16:42 ` Dmitry A. Kazakov 2011-08-30 18:57 ` Niklas Holsti 2011-08-31 16:39 ` Adam Beneschan 1 sibling, 1 reply; 21+ messages in thread From: Dmitry A. Kazakov @ 2011-08-30 16:42 UTC (permalink / raw) On Tue, 30 Aug 2011 08:38:52 -0700 (PDT), Adam Beneschan wrote: > I'm having a bit of difficulty figuring out from > the RM what the exact semantics of finalizing an unterminated task > object are, but I'm pretty sure that aborting the task is not one of > them. (Note that this applies only to tasks without discriminants. > If the task has discriminants, freeing it is an > error---13.11.2(11ff).) What is the difference? Is it an attempt to have freed tasks running further? Or an attempt to construct a race condition, e.g. when the task being freed has an open terminate alternative or else has been accepted a rendezvous and now is going down? Considering this standard pattern: type Object; task type Worker (Self : not null access Object'Class) is entry Shut_Down; end Worker; type Worker_Ptr is access Worker; type Object is new Ada.Finalization.Limited_Controlled with record Worker : Worker_Ptr; end Object; overriding procedure Finalize (This : in out Object); Now the following is a race with a bounded error: procedure Finalize (This : in out Object) is procedure Free is new Ada.Unchecked_Deallocation (...); begin if This.Worker /= null then This.Worker.Shut_Down; Free (This.Worker); end if; end Finalize; which shall be rewritten as: procedure Finalize (This : in out Object) is procedure Free is new Ada.Unchecked_Deallocation (...); begin if This.Worker /= null then This.Worker.Shut_Down; while not Worker'Terminated loop delay 0.1; end loop; Free (This.Worker); end if; end Finalize; Is it so? -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 16:42 ` Dmitry A. Kazakov @ 2011-08-30 18:57 ` Niklas Holsti 2011-08-30 19:23 ` Dmitry A. Kazakov 0 siblings, 1 reply; 21+ messages in thread From: Niklas Holsti @ 2011-08-30 18:57 UTC (permalink / raw) Dmitry A. Kazakov wrote: > On Tue, 30 Aug 2011 08:38:52 -0700 (PDT), Adam Beneschan wrote: > >> I'm having a bit of difficulty figuring out from >> the RM what the exact semantics of finalizing an unterminated task >> object are, but I'm pretty sure that aborting the task is not one of >> them. (Note that this applies only to tasks without discriminants. >> If the task has discriminants, freeing it is an >> error---13.11.2(11ff).) > > What is the difference? Is it an attempt to have freed tasks running > further? Or an attempt to construct a race condition, e.g. when the task > being freed has an open terminate alternative or else has been accepted a > rendezvous and now is going down? I assume that by "it" above, Dmitry is referring to the AdaCore notice about a change in the way Unchecked_Deallocation works in on tasks in GNAT, as quoted by Marc in his original post: "If Unchecked_Deallocation is called on a non-terminated task (which was previously a no-op), the task is now marked to be freed automatically when it terminates." It seems to me that the new behaviour is more useful than the old behaviour. > Considering this standard pattern: > > type Object; > task type Worker (Self : not null access Object'Class) is > entry Shut_Down; > end Worker; > type Worker_Ptr is access Worker; > type Object is new Ada.Finalization.Limited_Controlled with record > Worker : Worker_Ptr; > end Object; > overriding procedure Finalize (This : in out Object); (I don't think that the use of a controlled type is central to the example. Am I wrong, Dmitry?) > Now the following is a race with a bounded error: As I understand it, there was a race under the old behaviour, but not under the new behaviour. > procedure Finalize (This : in out Object) is > procedure Free is new Ada.Unchecked_Deallocation (...); > begin > if This.Worker /= null then > This.Worker.Shut_Down; > Free (This.Worker); With the old behaviour of Unchecked_Deallocation, the effect of this Free call depended on the state of This.Worker: if the task was not yet terminated, Free had no effect; if the task was terminated, Free deallocated the task object. With the new behaviour, the task object is always deallocated, either by the Free call (if the task is already terminated at that time) or by the RTS when the task terminates later, after the Free call. > end if; > end Finalize; > > which shall be rewritten as: Under the old behavior, this rewrite was necessary to ensure that the task is deallocated. Under the new behaviour, it is not necessary. As I understand it. > procedure Finalize (This : in out Object) is > procedure Free is new Ada.Unchecked_Deallocation (...); > begin > if This.Worker /= null then > This.Worker.Shut_Down; > while not Worker'Terminated loop > delay 0.1; > end loop; > Free (This.Worker); > end if; > end Finalize; -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 18:57 ` Niklas Holsti @ 2011-08-30 19:23 ` Dmitry A. Kazakov 0 siblings, 0 replies; 21+ messages in thread From: Dmitry A. Kazakov @ 2011-08-30 19:23 UTC (permalink / raw) On Tue, 30 Aug 2011 21:57:54 +0300, Niklas Holsti wrote: > Dmitry A. Kazakov wrote: >> On Tue, 30 Aug 2011 08:38:52 -0700 (PDT), Adam Beneschan wrote: >> >>> I'm having a bit of difficulty figuring out from >>> the RM what the exact semantics of finalizing an unterminated task >>> object are, but I'm pretty sure that aborting the task is not one of >>> them. (Note that this applies only to tasks without discriminants. >>> If the task has discriminants, freeing it is an >>> error---13.11.2(11ff).) >> >> What is the difference? Is it an attempt to have freed tasks running >> further? Or an attempt to construct a race condition, e.g. when the task >> being freed has an open terminate alternative or else has been accepted a >> rendezvous and now is going down? > > I assume that by "it" above, Dmitry is referring to the AdaCore notice > about a change in the way Unchecked_Deallocation works in on tasks in > GNAT, as quoted by Marc in his original post: No, I meant the rationale behind ARM 13.11.2(11), which looks dubious to me. > "If Unchecked_Deallocation is called on a non-terminated task (which was > previously a no-op), the task is now marked to be freed automatically > when it terminates." > > It seems to me that the new behaviour is more useful than the old behaviour. Maybe. But it is unclear if it is consistent with the expectations of a naive user. Which is: Unchecked_Deallocation awaits for the task termination and then frees whatever memory the task is using. >> Considering this standard pattern: >> >> type Object; >> task type Worker (Self : not null access Object'Class) is >> entry Shut_Down; >> end Worker; >> type Worker_Ptr is access Worker; >> type Object is new Ada.Finalization.Limited_Controlled with record >> Worker : Worker_Ptr; >> end Object; >> overriding procedure Finalize (This : in out Object); > > (I don't think that the use of a controlled type is central to the > example. Am I wrong, Dmitry?) It is the most common case when a task has a discriminant. Since task as a component is a non-starter, the only work-around would be a controlled type removing its access-to-task component from Finalize. >> Now the following is a race with a bounded error: > > As I understand it, there was a race under the old behaviour, but not > under the new behaviour. Well, it could be read as if the choice offered by ARM 13.11.2(12) was taken. Though according to ARM, it is still a bounded error, and maybe even worse than that (see the scenario below). >> procedure Finalize (This : in out Object) is >> procedure Free is new Ada.Unchecked_Deallocation (...); >> begin >> if This.Worker /= null then >> This.Worker.Shut_Down; >> Free (This.Worker); > > With the old behaviour of Unchecked_Deallocation, the effect of this > Free call depended on the state of This.Worker: if the task was not yet > terminated, Free had no effect; if the task was terminated, Free > deallocated the task object. > > With the new behaviour, the task object is always deallocated, either by > the Free call (if the task is already terminated at that time) or by > the RTS when the task terminates later, after the Free call. This is unclear. Because if Free is not blocked, the Object's Finalize continues, possibly ends (and then the object is freed), while the task is still running and possibly accessing the object through its discriminant. This kind of error is unbounded in contradiction to ARM 13.11.2(11). It would be rather catastrophic behavior. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 15:38 ` Adam Beneschan 2011-08-30 16:42 ` Dmitry A. Kazakov @ 2011-08-31 16:39 ` Adam Beneschan 2011-08-31 18:21 ` Robert A Duff 2011-08-31 20:30 ` J-P. Rosen 1 sibling, 2 replies; 21+ messages in thread From: Adam Beneschan @ 2011-08-31 16:39 UTC (permalink / raw) On Aug 30, 8:38 am, Adam Beneschan <a...@irvine.com> wrote: > I think this is right---the task continues to function until it > terminates. The only way to get a task to stop executing before it > completes is to abort it (via an abort statement, or other semantics > that cause an abort---see 9.8). An Unchecked_Deallocation instance > finalizes the task object, but the semantics of finalization don't > involve aborting. I'm having a bit of difficulty figuring out from > the RM what the exact semantics of finalizing an unterminated task > object are, but I'm pretty sure that aborting the task is not one of > them. Actually, I just found this in the Ada 83 manual (13.10.1(8)): "If X designates a task object, the call FREE(X) [where FREE is an instance of Unchecked_Deallocation] has no effect on the task desginated by the value of the task object. The same holds for any subcomponent of the object designated by X, if this subcomponent is a task object." This language got dropped in Ada 95, but I think it was intended that these still be the semantics, for a task without discriminants (Ada 83 did not allow task discriminants). I'm not sure why the language was omitted; it could have just been inadvertent (I've seen one or two other cases where RM83 language got lost and left some things undefined that should have been defined), or the authors could have felt that it was no longer necessary because of other wording changes, particularly those dealing with finalization. The latter could be correct, although I've been having trouble finding RM language that made it clear that this was supposed to happen. The current RM does say that "if the object being freed contains tasks, the object might not be deallocated", but this doesn't clearly say anything about what happens to the task. One thing that bothers me a bit, although I don't know if it bothers me enough to request an RM change: 13.11.2(10) says that after Free(X), the designated object and its subcomponents no longer exist. 9.1(15-18) says that the content of a task object includes entry queues for the task. I'm willing to accept that there is a distinction between a task object and a task (or a task execution), but if the task object no longer exists, does that mean that the entry queues that it contains no longer exist, and that therefore if another task Y was waiting on X.all's entry when X was freed, so that the entry queue on which Y was sitting no longer exists, does Y's entry call get cancelled? Again, I don't think this is the intent, but I'm not sure. -- Adam ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 16:39 ` Adam Beneschan @ 2011-08-31 18:21 ` Robert A Duff 2011-08-31 23:28 ` Adam Beneschan 2011-08-31 20:30 ` J-P. Rosen 1 sibling, 1 reply; 21+ messages in thread From: Robert A Duff @ 2011-08-31 18:21 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> writes: > Actually, I just found this in the Ada 83 manual (13.10.1(8)): > > "If X designates a task object, the call FREE(X) [where FREE is an > instance of Unchecked_Deallocation] has no effect on the task > desginated by the value of the task object. The same holds for any > subcomponent of the object designated by X, if this subcomponent is a > task object." > > This language got dropped in Ada 95, but I think it was intended that > these still be the semantics, for a task without discriminants (Ada 83 > did not allow task discriminants). I'm not sure why the language was > omitted; ... It might have to do with the fact that task values don't formally "designate" anymore. Anyway, it doesn't need to say anything. If it doesn't say anything happens to the task, then nothing happens -- it just keeps running. It doesn't say U_D waits for it to terminate. It doesn't say U_D aborts it. It doesn't say that U_D should set all variables to 17. So none of these things happen. > One thing that bothers me a bit, although I don't know if it bothers > me enough to request an RM change: I suggestion you refrain. ;-) This sort of nitpicking is just a waste of time for the ARG. Any wording change wouldn't affect the behavior of any programmer, nor any implementer, so why bother? - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 18:21 ` Robert A Duff @ 2011-08-31 23:28 ` Adam Beneschan 2011-09-01 11:58 ` Robert A Duff 0 siblings, 1 reply; 21+ messages in thread From: Adam Beneschan @ 2011-08-31 23:28 UTC (permalink / raw) On Aug 31, 11:21 am, Robert A Duff <bobd...@shell01.TheWorld.com> wrote: > Adam Beneschan <a...@irvine.com> writes: > > Actually, I just found this in the Ada 83 manual (13.10.1(8)): > > > "If X designates a task object, the call FREE(X) [where FREE is an > > instance of Unchecked_Deallocation] has no effect on the task > > desginated by the value of the task object. The same holds for any > > subcomponent of the object designated by X, if this subcomponent is a > > task object." > > > This language got dropped in Ada 95, but I think it was intended that > > these still be the semantics, for a task without discriminants (Ada 83 > > did not allow task discriminants). I'm not sure why the language was > > omitted; ... > > It might have to do with the fact that task values don't formally > "designate" anymore. But access objects do, and in the RM83 paragraph, X is an access object. > Anyway, it doesn't need to say anything. > If it doesn't say anything happens to the task, then nothing > happens -- it just keeps running. It doesn't say U_D waits > for it to terminate. It doesn't say U_D aborts it. It doesn't > say that U_D should set all variables to 17. So none of these > things happen. Perhaps. But the fact that we've seen two different incorrect assumptions about what this does to the task (one thought the task would immediately terminate, as if it were aborted, and another thought it would wait for the task to terminate) means that maybe it would be helpful to add the RM83 language back in (for nondiscriminated tasks). By the way, the only way one can know that the RM doesn't say anything happens to the task is to read and fully understand the entire RM, since otherwise one never knows what other semantics there are elsewhere in the RM that may answer the question or that may combine to give an answer to the question. I studied 7.6.1 and several sections in Chapter 9 pretty thoroughly before concluding that the RM didn't say that anything happened to the task. And that's not helpful to someone who's consulting the RM to try to find out how things work. Keep in mind that the R in RM does stand for something. -- Adam ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 23:28 ` Adam Beneschan @ 2011-09-01 11:58 ` Robert A Duff 0 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 2011-09-01 11:58 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> writes: > On Aug 31, 11:21�am, Robert A Duff <bobd...@shell01.TheWorld.com> > wrote: >> Adam Beneschan <a...@irvine.com> writes: >> > Actually, I just found this in the Ada 83 manual (13.10.1(8)): >> >> > "If X designates a task object, the call FREE(X) [where FREE is an >> > instance of Unchecked_Deallocation] has no effect on the task >> > desginated by the value of the task object. �The same holds for any >> > subcomponent of the object designated by X, if this subcomponent is a >> > task object." >> >> > This language got dropped in Ada 95, but I think it was intended that >> > these still be the semantics, for a task without discriminants (Ada 83 >> > did not allow task discriminants). �I'm not sure why the language was >> > omitted; ... >> >> It might have to do with the fact that task values don't formally >> "designate" anymore. > > But access objects do, and in the RM83 paragraph, X is an access > object. Right, but there are two "designate" in the Ada 83 wording. I was referring to the second one. In Ada 83, a task object contains a task value, which is a pointer that designates a task. So if you have an access-to-task object, it's value designates a task object whose value designates the task. >...By the way, the only way one can know that > the RM doesn't say anything happens to the task is to read and fully > understand the entire RM, ... Yeah, that's a problem. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 16:39 ` Adam Beneschan 2011-08-31 18:21 ` Robert A Duff @ 2011-08-31 20:30 ` J-P. Rosen 2011-08-31 22:36 ` Adam Beneschan 1 sibling, 1 reply; 21+ messages in thread From: J-P. Rosen @ 2011-08-31 20:30 UTC (permalink / raw) Le 31/08/2011 18:39, Adam Beneschan a �crit : > One thing that bothers me a bit, although I don't know if it bothers > me enough to request an RM change: 13.11.2(10) says that after > Free(X), the designated object and its subcomponents no longer exist. > 9.1(15-18) says that the content of a task object includes entry > queues for the task. I'm willing to accept that there is a > distinction between a task object and a task (or a task execution), > but if the task object no longer exists, does that mean that the entry > queues that it contains no longer exist, and that therefore if another > task Y was waiting on X.all's entry when X was freed, so that the > entry queue on which Y was sitting no longer exists, does Y's entry > call get cancelled? Again, I don't think this is the intent, but I'm > not sure. > As soon as a task iscompleted, all waiting tasks receive Tasking_Error. Since the space is (hopefully!) deallocated after the task is completed (and even terminated), there is no problem. -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Adalog a d�m�nag� / Adalog has moved: 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 20:30 ` J-P. Rosen @ 2011-08-31 22:36 ` Adam Beneschan 2011-09-01 5:24 ` J-P. Rosen 0 siblings, 1 reply; 21+ messages in thread From: Adam Beneschan @ 2011-08-31 22:36 UTC (permalink / raw) On Aug 31, 1:30 pm, "J-P. Rosen" <ro...@adalog.fr> wrote: > Le 31/08/2011 18:39, Adam Beneschan a écrit :> One thing that bothers me a bit, although I don't know if it bothers > > me enough to request an RM change: 13.11.2(10) says that after > > Free(X), the designated object and its subcomponents no longer exist. > > 9.1(15-18) says that the content of a task object includes entry > > queues for the task. I'm willing to accept that there is a > > distinction between a task object and a task (or a task execution), > > but if the task object no longer exists, does that mean that the entry > > queues that it contains no longer exist, and that therefore if another > > task Y was waiting on X.all's entry when X was freed, so that the > > entry queue on which Y was sitting no longer exists, does Y's entry > > call get cancelled? Again, I don't think this is the intent, but I'm > > not sure. > > As soon as a task iscompleted, all waiting tasks receive Tasking_Error. > Since the space is (hopefully!) deallocated after the task is completed > (and even terminated), there is no problem. But I'm not talking about a task being completed. It's pretty clear that it's possible to use Unchecked_Deallocation on an object that contains an access to a task, and this Unchecked_Deallocation can complete, without the task being completed. But this means that the task *object* (which isn't the same as a task, I think) ceases to exist, even though the task still hasn't completed; and a literal (but possibly absurd) reading of the RM would mean that the task's entry queues no longer exist (even though the task still hasn't completed), leading to questions about what happens to tasks that are already on those queues. -- Adam ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-31 22:36 ` Adam Beneschan @ 2011-09-01 5:24 ` J-P. Rosen 0 siblings, 0 replies; 21+ messages in thread From: J-P. Rosen @ 2011-09-01 5:24 UTC (permalink / raw) Le 01/09/2011 00:36, Adam Beneschan a �crit : > But I'm not talking about a task being completed. It's pretty clear > that it's possible to use Unchecked_Deallocation on an object that > contains an access to a task, and this Unchecked_Deallocation can > complete, without the task being completed. But this means that the > task *object* (which isn't the same as a task, I think) ceases to > exist, even though the task still hasn't completed; and a literal (but > possibly absurd) reading of the RM would mean that the task's entry > queues no longer exist (even though the task still hasn't completed), > leading to questions about what happens to tasks that are already on > those queues. > TBH, I didn't even think that anybody (human, RM, or implementation) would even consider freeing part of a task's space before the task is completed ;-) -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Adalog a d�m�nag� / Adalog has moved: 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Delayed deallocation of non-terminated task in Gnat? 2011-08-30 13:22 Delayed deallocation of non-terminated task in Gnat? Marc C 2011-08-30 15:20 ` Dmitry A. Kazakov 2011-08-30 15:38 ` Adam Beneschan @ 2011-08-31 18:08 ` Robert A Duff 2 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 2011-08-31 18:08 UTC (permalink / raw) Marc C <mc.provisional@gmail.com> writes: > This *looks* to me like one could dynamically allocate a task instance > and then immediately free it with an instantiation of > Unchecked_Deallocation, yet the task would continue to function > normally until it terminates. Yes. Ada semantics requires that if you call Unchecked_Deallocation on an object that contains running tasks, the tasks keep running. In the old version of GNAT, U_D would say "Is the task terminated? If so, free up its resources. If not, do nothing." So it could leak memory. The new version of GNAT is better: "Is the task terminated? If so, free up its resources. If not, cause its resources to be freed up when it does terminate." But you have to be careful: Like any U_D, you can have dangling pointers. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2011-09-01 11:58 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-08-30 13:22 Delayed deallocation of non-terminated task in Gnat? Marc C 2011-08-30 15:20 ` Dmitry A. Kazakov 2011-08-31 18:12 ` Robert A Duff 2011-08-31 19:23 ` Dmitry A. Kazakov 2011-08-31 20:58 ` Robert A Duff 2011-08-31 21:16 ` Jeffrey Carter 2011-08-31 20:25 ` J-P. Rosen 2011-08-31 21:09 ` Robert A Duff 2011-08-31 21:53 ` Simon Wright 2011-08-30 15:38 ` Adam Beneschan 2011-08-30 16:42 ` Dmitry A. Kazakov 2011-08-30 18:57 ` Niklas Holsti 2011-08-30 19:23 ` Dmitry A. Kazakov 2011-08-31 16:39 ` Adam Beneschan 2011-08-31 18:21 ` Robert A Duff 2011-08-31 23:28 ` Adam Beneschan 2011-09-01 11:58 ` Robert A Duff 2011-08-31 20:30 ` J-P. Rosen 2011-08-31 22:36 ` Adam Beneschan 2011-09-01 5:24 ` J-P. Rosen 2011-08-31 18:08 ` Robert A Duff
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox