2001-04-09 20:54:03 +01:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* YAP Prolog *
|
|
|
|
* *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: timeout.yap *
|
|
|
|
* Last rev: 5/12/99 *
|
|
|
|
* mods: *
|
|
|
|
* comments: Goal within timeout *
|
|
|
|
* *
|
|
|
|
*************************************************************************/
|
|
|
|
|
2015-11-18 15:06:25 +00:00
|
|
|
/**
|
|
|
|
* @file timeout.yap
|
|
|
|
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
|
|
|
|
* @date Wed Nov 18 01:26:14 2015
|
|
|
|
*
|
|
|
|
* @brief Calls With Timeout
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
:- module(timeout, [
|
|
|
|
time_out/3
|
|
|
|
]).
|
|
|
|
|
2014-09-11 20:06:57 +01:00
|
|
|
|
2015-11-18 15:06:25 +00:00
|
|
|
/** @defgroup timeout Calls With Timeout
|
2015-01-04 23:58:23 +00:00
|
|
|
@ingroup library
|
2014-09-11 20:06:57 +01:00
|
|
|
@{
|
|
|
|
|
|
|
|
The <tt>time_out/3</tt> command relies on the <tt>alarm/3</tt> built-in to
|
|
|
|
implement a call with a maximum time of execution. The command is
|
|
|
|
available with the `use_module(library(timeout))` command.
|
|
|
|
|
2018-05-01 23:25:58 +01:00
|
|
|
*/
|
2014-09-11 20:06:57 +01:00
|
|
|
|
2018-05-01 23:25:58 +01:00
|
|
|
/*
|
|
|
|
|
2014-09-11 20:06:57 +01:00
|
|
|
@pred time_out(+ _Goal_, + _Timeout_, - _Result_)
|
|
|
|
|
|
|
|
|
|
|
|
Execute goal _Goal_ with time limited _Timeout_, where
|
|
|
|
_Timeout_ is measured in milliseconds. If the goal succeeds, unify
|
|
|
|
_Result_ with success. If the timer expires before the goal
|
|
|
|
terminates, unify _Result_ with <tt>time_out</tt>.
|
|
|
|
|
|
|
|
This command is implemented by activating an alarm at procedure
|
|
|
|
entry. If the timer expires before the goal completes, the alarm will
|
|
|
|
throw an exception _timeout_.
|
|
|
|
|
|
|
|
One should note that time_out/3 is not reentrant, that is, a goal
|
|
|
|
called from `time_out` should never itself call
|
|
|
|
time_out/3. Moreover, time_out/3 will deactivate any previous
|
|
|
|
alarms set by alarm/3 and vice-versa, hence only one of these
|
|
|
|
calls should be used in a program.
|
|
|
|
|
|
|
|
Last, even though the timer is set in milliseconds, the current
|
|
|
|
implementation relies on <tt>alarm/3</tt>, and therefore can only offer
|
|
|
|
precision on the scale of seconds.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2010-04-22 21:05:34 +01:00
|
|
|
:- meta_predicate time_out(0,+,-).
|
2001-04-09 20:54:03 +01:00
|
|
|
|
2009-06-02 03:30:56 +01:00
|
|
|
:- use_module(library(hacks), [
|
|
|
|
virtual_alarm/3
|
|
|
|
]).
|
|
|
|
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
%
|
|
|
|
% not the nicest program I've ever seen.
|
|
|
|
%
|
2009-05-27 21:54:05 +01:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
time_out(Goal, Time, Result) :-
|
|
|
|
T is Time//1000,
|
2007-05-21 00:00:38 +01:00
|
|
|
UT is (Time mod 1000)*1000,
|
2009-05-27 21:54:05 +01:00
|
|
|
catch( ( Result0 = success,
|
2009-05-28 00:15:02 +01:00
|
|
|
setup_call_cleanup(
|
2009-06-02 03:30:56 +01:00
|
|
|
virtual_alarm(T.UT,throw(time_out),_),
|
2009-05-27 21:54:05 +01:00
|
|
|
Goal,
|
2009-06-02 03:30:56 +01:00
|
|
|
virtual_alarm(0,_,RT)),
|
2009-05-27 21:54:05 +01:00
|
|
|
( var(RT)
|
2009-06-02 03:30:56 +01:00
|
|
|
-> virtual_alarm(0,_,_),
|
2009-06-02 01:49:03 +01:00
|
|
|
(
|
|
|
|
true
|
|
|
|
;
|
2009-06-02 03:30:56 +01:00
|
|
|
virtual_alarm(T.UT,throw(time_out),_),
|
2009-06-02 01:49:03 +01:00
|
|
|
fail
|
|
|
|
)
|
2009-05-27 21:54:05 +01:00
|
|
|
; true
|
|
|
|
)
|
|
|
|
),
|
|
|
|
time_out,
|
|
|
|
Result0 = time_out ),
|
2009-05-19 17:10:51 +01:00
|
|
|
Result = Result0.
|
2017-04-07 23:10:59 +01:00
|
|
|
|
|
|
|
%% @}
|
|
|
|
|