Subject: Re: [SWIPL] FW: call_with_time_limit/2

From: Jan Wielemaker <[email-masked]>
Date: Wed, 5 Dec 2001 14:16:26 +0100

On Tue, 04 Dec 2001, Douglas R. Miles wrote:

>I am geting a PrologCall() Error,
>
>Here is my program (We are using the Multithread SWI-Prolog 4.0.10):

<snip>

>:- module_transparent call_with_time_limit/2. 
>% Max time in seconds 
>	call_with_time_limit(Goal, MaxTime) :- 
>      	  thread_self(Target), 
>	        thread_create(Timer, 
>                (( 
>                       sleep(MaxTime), 
>	
>catch(ignore(thread_signal(Target,throw(giveup))),_,true), 
>                        thread_exit(completed) 
>               )),[detatched]), 
>	  retractall(timer_thread(Targer,_)), 
>        asserta(timer_thread(Targer,Timer)),
>	catch(Goal, giveup, fail), !. 
>
>call_with_time_limit(_, _) :- 
>      etract(timer_thread(Targer,Timer)), 
>	
>catch(ignore(thread_signal(Timer,thread_exit(iWasDoneFirst))),_,true), 
>      fail. 

The poor error message has been fixed.  You're reversing the argument
order of thread_create, which is defined as thread_create(:Goal, -Id,
+Options).

Next, I think your solution is way too simple.  It works fine on a
timeout, but without the timer-thread will finish its sleep/1 before
honouring the signal and thus you may create an enormous amount of
sleeping threads.

I think the correct solution is to define a signalling thread.  This
thread can be asked to deliver a message at a specific time as well
as de-queue a scheduled message.

Roughly, such a thread can be created using the pipe/2 call from the
libc package to create a pipe between the rest of the environment and
the timer-thread.  Messages are send to the timer thread by writing to
this pipe.  The timer thread performes a time-ed wait_for_input/3 on the
pipe.  If it receives a message over the pipe it computes the time to
the next message to send and sleeps again.  If it gets a timeout it
sends its signal, computes the new timeout, etc.

	Cheers --- Jan