From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: task time-out&abort
Date: Mon, 18 Jul 2005 12:11:47 -0400
Date: 2005-07-18T12:11:47-04:00 [thread overview]
Message-ID: <5eWdnYcV-YxHSUbfRVn-1g@comcast.com> (raw)
In-Reply-To: <wccwtocsx6i.fsf@shell01.TheWorld.com>
(The point of this post is to give some guidance on which approach to
use...)
Robert A Duff wrote:
>
> You can put the Horribly_Complicated_Recursive_Function inside an ATC:
>
> select
> delay 5.0;
> then abort
> Horribly_Complicated_Recursive_Function...
> end select;
>
> And you can pass the time-out as a parameter to the entry call,
> if you like.
This is the right idiom for handling ill-behaved computations. But as
written it is infrequently the best/right solution.
> But be careful! ATC is a very dangerous feature, which is difficult to
> get right. And if you get it wrong, you will have nasty
> timing-dependent bugs.
Should I repeat this three times?
>
> The problem is that any variables modified by
> Horribly_Complicated_Recursive_Function can be destroyed
> when it gets aborted by the timeout. The usual way to deal with it
> is to do most of the work in local data that nobody else looks at.
> And it can update some more-global thing (like an 'out' parameter of the
> entry) in an abort-deferred way -- using a protected object, or a pragma
> Atomic.
Exactly, and the reason I am commmenting here. There are really three
cases:
1) You have no control over and no insight into the Horribly Complicated
Recursive Function. In this case, if the timeout happens, your only
option to (possibly) get a usable result is to start over with a longer
delay.
2) A much more normal case is that you are doing some sort of iterative
refinement. In this case, as Bob points out, you can use a protected
object to collect each improved result, and when the abort occurs, you
can use the best result found in the time available. This is a common
idiom in flight control software, although the preferred implementation
computes how long the next iteration will take, and checks to see if
there is enough time remaining. (This way you always finish in less
time than is available, instead of potentially taking a few hundred
cycles longer.)
3) A nicer implementation in Ada using tasking is possible when each
iteration takes a limited (and short) time. This is the implementation
that has been suggested where the Horribly Complicated Recursive
Function is wrapped in a task that checks whether the timeout entry has
been called.
4) The last solution is not to use tasking at all:
declare
Finish: Ada.Calendar.Time := Ada.Calendar.Clock + Timeout -
Iteration_Time_Limit;
begin
while Ada.Calendar.Clock < Finish loop
Do_Iteration;
end loop;
end;
-- use results here.
This of course requires that Horribly Complicated Recursive Function can
be broken into iterations that are limited in the time required to
complete. We are actually back to the beginning at this point, since
you can use the idioms above to ensure that each iteration completes
within the time limit.
prev parent reply other threads:[~2005-07-18 16:11 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-22 18:08 task time-out&abort e.coli
2005-06-22 18:40 ` Dmitry A. Kazakov
2005-06-23 10:11 ` e.coli
2005-06-23 10:59 ` Dmitry A. Kazakov
2005-06-22 19:44 ` Mark Lorenzen
2005-06-23 1:44 ` Steve
2005-06-23 15:26 ` e.coli
2005-06-23 17:01 ` e.coli
2005-06-24 11:42 ` Marius Amado Alves
2005-06-28 21:31 ` Robert A Duff
2005-06-29 0:32 ` Marius Amado Alves
2005-06-29 20:52 ` Robert A Duff
2005-07-18 16:11 ` Robert I. Eachus [this message]
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox