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). |