1 % (c) 2009-2024 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5
6 :- module(tools_timeout, [
7 time_out_call/2, time_out_call/1,
8 time_out_with_factor_call/3, time_out_with_factor_call/4,
9 get_time_out_with_factor/2
10 ]).
11
12 :- use_module(module_information).
13
14 :- module_info(group,infrastructure).
15 :- module_info(description,'This module contains higher-level timeout helper predicates.').
16
17
18 :- meta_predicate time_out_with_factor_call(0,*,0).
19 :- meta_predicate time_out_with_factor_call(0,*,*,0).
20 :- meta_predicate time_out_call(0,0).
21 :- meta_predicate time_out_call(0).
22
23 :- use_module(tools_meta,[safe_time_out/3]).
24 :- use_module(tools_printing,[print_term_summary/1]).
25 :- use_module(error_manager,[add_message/3, add_error_and_fail/3]).
26 :- use_module(tools_strings,[predicate_functor/3]).
27 :- use_module(preferences,[get_preference/2]).
28
29 time_out_call(Call,BackupCall) :-
30 get_preference(time_out,CurTO),
31 safe_time_out(Call,CurTO,TimeOutRes),
32 (TimeOutRes=time_out
33 -> predicate_functor(Call,F,N),
34 add_message(self_check,'Time out occurred: ',F/N),
35 print_term_summary(Call),
36 %% portray_clause(Call), %%
37 call(BackupCall)
38 ; true).
39
40 time_out_call(Call) :-
41 time_out_call(Call,add_error_and_fail(time_out_call,'*** TIMEOUT occurred: ',Call)).
42
43 :- use_module(preferences,[get_time_out_preference_with_factor/2]).
44 get_time_out_with_factor(fixed_time_out(Fixedms),TORes) :- % also allow to specify a hard time out value
45 !, TORes = Fixedms.
46 get_time_out_with_factor(min_max_time_out(Factor,MinFixedms,MaxFixedms),TORes) :-
47 !,
48 get_time_out_preference_with_factor(Factor,Res),
49 (Res > MaxFixedms -> TORes = MaxFixedms;
50 Res < MinFixedms -> TORes = MinFixedms
51 ; TORes=Res).
52 get_time_out_with_factor(Factor,Res) :-
53 get_time_out_preference_with_factor(Factor,Res).
54
55
56 time_out_with_factor_call(Call,Factor,TimeOutCode) :-
57 time_out_with_factor_call(Call,Factor,[],TimeOutCode).
58 time_out_with_factor_call(Call,Factor,Options,TimeOutCode) :-
59 get_time_out_with_factor(Factor,TO1),
60 %%print(time_out(Call,TO)),nl,
61 % TODO: print small message if time-out is larger than say 2 minutes?
62 (member(max_time_out(MaxTO),Options), TO1 > MaxTO
63 -> TO = MaxTO ; TO=TO1),
64 statistics(runtime,[Start,_]),
65 ? catch(
66 safe_time_out(Call,TO,TimeOutRes),
67 enumeration_warning(_,_,_,_,_),
68 (TimeOutRes = time_out,EnumWarning=true)),
69 (TimeOutRes=time_out
70 -> (member(silent,Options) -> true
71 ; statistics(runtime,[Stop,_]),
72 predicate_functor(Call,F,N),
73 (EnumWarning==true
74 -> add_message(self_check,'Time-out forced by enumeration warning: ',F/N)
75 ; add_message(self_check,'Time-out occurred: ',F/N)
76 ),
77 print_term_summary(Call),
78 Diff is Stop-Start,
79 print(Diff), print(' ms runtime (time_out = '), print(TO), print(' ms)'),nl
80 ),
81 call(TimeOutCode)
82 ; true).