From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,a0f8bfc88538cab5 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!news.glorb.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.comcast.com!news.comcast.com.POSTED!not-for-mail NNTP-Posting-Date: Mon, 18 Jul 2005 11:12:10 -0500 Date: Mon, 18 Jul 2005 12:11:47 -0400 From: "Robert I. Eachus" User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: task time-out&abort References: <1119463703.048124.135330@o13g2000cwo.googlegroups.com> <1119540379.606416.227950@z14g2000cwz.googlegroups.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Message-ID: <5eWdnYcV-YxHSUbfRVn-1g@comcast.com> NNTP-Posting-Host: 24.147.79.61 X-Trace: sv3-2dRZhQNnHhv1l7OnDNOgFzY2NikRx3xcJZh38eoYlxqjTws6D7o3k/ZB3UjnJ6hEV+K0nEHCC+CzvFf!zIYNvRQ4LSVgdxs8U5MnsaJku07s/YQ0NQD88xRBaio9SvaVGRqHE7yXJEtvPn16PwVeZpOUicA= X-Complaints-To: abuse@comcast.net X-DMCA-Complaints-To: dmca@comcast.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news1.google.com comp.lang.ada:3663 Date: 2005-07-18T12:11:47-04:00 List-Id: (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.