From jan@swi.swi.psy.uva.nl Wed Dec  5 14:27:00 2001
Received: from gollem.swi.psy.uva.nl (gollem.swi.psy.uva.nl [145.18.152.30])
	by swi.psy.uva.nl (8.10.2+Sun/8.11.2) with ESMTP id fB5DR0k19483;
	Wed, 5 Dec 2001 14:27:00 +0100 (MET)
Received: from localhost (localhost [[UNIX: localhost]])
	by gollem.swi.psy.uva.nl (8.11.3/8.11.3/SuSE Linux 8.11.1-0.5) id fB5DQr603804;
	Wed, 5 Dec 2001 14:26:53 +0100
From: Jan Wielemaker <jan@swi.psy.uva.nl>
Organization: SWI, University of Amsterdam
To: "Douglas R. Miles" <dmiles@teknowledge.com>,
   "'prolog@swi.psy.uva.nl'" <prolog@swi.swi.psy.uva.nl>
Subject: Re: [SWIPL] FW: call_with_time_limit/2
Date: Wed, 5 Dec 2001 14:16:26 +0100
X-Mailer: KMail [version 1.0.29.2]
Content-Type: text/plain
Cc: John Li <jli@teknowledge.com>, "Douglas R. Miles" <dmiles@teknowledge.com>
References: <EE25484266A64A47AE06CFC47C64232B403C79@helium.teknowledge.com>
In-Reply-To: <EE25484266A64A47AE06CFC47C64232B403C79@helium.teknowledge.com>
MIME-Version: 1.0
Message-Id: <01120514265307.30497@gollem>
Content-Transfer-Encoding: 8bit

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

