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