1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 2002-2023, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38:- module(time, 39 [ alarm/3, % +Time, :Callable, -Id 40 alarm/4, % +Time, :Callable, -Id, +Options 41 alarm_at/3, % +Time, :Callable, -Id 42 alarm_at/4, % +Time, :Callable, -Id, +Options 43 remove_alarm/1, % +Id 44 install_alarm/1, % +Id 45 install_alarm/2, % +Id, +Time 46 uninstall_alarm/1, % +Id 47 current_alarm/4, % ?At, ?:Goal, ?Id, ?Status 48 call_with_time_limit/2, % +Time, :Callable 49 call_with_time_limit/3 % +Time, :Callable, +Context 50 ]). 51:- autoload(library(lists),[member/2]). 52 53:- set_prolog_flag(generate_debug_info, false). 54 55:- meta_predicate 56 call_with_time_limit( , ), 57 call_with_time_limit( , , ), 58 alarm( , , ), 59 alarm( , , , ), 60 alarm_at( , , , ), 61 current_alarm( , , , ). 62 63:- predicate_options(alarm/4, 4, 64 [ remove(boolean), 65 install(boolean) 66 ]).
Options is a list of Name(Value) options. Currently defined options are:
true
(default false
), remove the alarm-event (as
remove_alarm/1) after it has been fired.false
(default true
) do not install the alarm.
It must be installed separately using install_alarm/1.install(false)
option or de-activated using uninstall_alarm/1. With a given
RelTime, the alarm is scheduled at the RelTime from now.
Otherwise it is scheduled on the same (absolute) time on which
is was created.done
if the alarm has
been fired, next
if the event is the next to be executed and
scheduled
otherwise.134:- use_foreign_library(foreign(time)). 135:- public time_debug/1. % set debugging
time_limit_exceeded
is raised.
call_with_time_limit/3 throws time_limit_exceeded(Context)
. Goal is
called as in once/1.
148call_with_time_limit(Time, Goal) :- 149 call_with_time_limit(Time, Goal, '$no_ctx'). 150 151call_with_time_limit(Time, Goal, Ctx) :- 152 Time > 0, 153 !, 154 setup_call_cleanup(alarm(Time, time_limit_exceeded(Time, Ctx), 155 Id, [install(false)]), 156 run_alarm_goal(Id, Goal), 157 remove_alarm_notrace(Id)). 158call_with_time_limit(_Time, _Goal, _Ctx) :- 159 throw(time_limit_exceeded). 160 161run_alarm_goal(AlarmID, Goal) :- 162 install_alarm(AlarmID), 163 , 164 !. 165 166time_limit_exceeded(_Time, Ctx) :- 167 ( Ctx == '$no_ctx' 168 -> throw(time_limit_exceeded) 169 ; throw(time_limit_exceeded(Ctx)) 170 ). 171 172current_alarm(Time, Goal, Id, Status) :- 173 current_alarms(Time, Goal, Id, Status, List), 174 member(alarm(Time, Goal, Id, Status), List). 175 176 /******************************* 177 * HANDLE MESSAGES * 178 *******************************/ 179 180:- multifile 181 prolog:message/3. 182 183prologmessage(time_limit_exceeded) --> 184 [ 'Time limit exceeded' ]. 185prologmessage(time_limit_exceeded(Context)) --> 186 [ 'Time limit exceeded: ~p'-[Context] ]. 187 188 /******************************* 189 * ALARM * 190 *******************************/ 191 192:- multifile sandbox:safe_meta_predicate/1. 193 194sandbox:safe_meta_predicate(time:call_with_time_limit/2)
Time and alarm library
The library(time) provides timing and alarm functions. Alarms are thread-specific, i.e., creating an alarm causes the alarm goal to be called in the thread that created it. The predicate current_alarm/4 only reports alarms that are related to the calling thread. If a thread terminates, all remaining alarms are silently removed. Most applications use call_with_time_limit/2. */