forked from SWI-Prolog/packages-clib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_time.pl
133 lines (108 loc) · 2.52 KB
/
test_time.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
:- module(test_time,
[ test_time/0,
list_alarms/0
]).
:- use_module(library(debug)).
:- use_module(library(plunit)).
:- asserta(file_search_path(foreign, '.')).
:- [time].
dbg :-
time:time_debug(1).
test_time :-
run_tests([ time
]).
:- begin_tests(time).
test(current) :-
setup_call_cleanup(alarm(5.0, writeln(ouch), ID, []),
current_alarm(_At, _Goal, ID, _Status),
remove_alarm(ID)).
test(current) :-
setup_call_cleanup(alarm(5.0, writeln(ouch), ID, []),
current_alarm(_At, writeln(ouch), _ID, _Status),
remove_alarm(ID)).
test(current) :-
setup_call_cleanup(alarm(5.0, writeln(ouch), ID, []),
current_alarm(_At, _Goal, _ID, scheduled),
remove_alarm(ID)).
test(bg) :-
bg(4).
test(flood) :-
flood_test.
:- end_tests(time).
/*******************************
* MULTI-THREAD TIMEOUT *
*******************************/
bg(N) :-
findall(Id, (between(1, N, _),
thread_create(t(100, 0.05), Id, [])),
IDS),
join_all(IDS).
join_all([]).
join_all([H|T]) :-
thread_join(H, Status),
assertion(Status == true),
join_all(T).
t(N, Time) :-
thread_create(worker, Worker, []),
t(N, Time, Worker),
thread_send_message(Worker, done),
thread_join(Worker, Status),
assertion(Status == true).
t(0, _, _) :- !.
t(N, Time, Worker) :-
thread_self(Me),
thread_send_message(Worker, work(Time, Me)),
thread_get_message(done(E)),
assertion(E == time_limit_exceeded),
N2 is N - 1,
t(N2, Time, Worker).
worker :-
thread_get_message(Msg),
( Msg = work(N, Sender)
-> thread_self(Me),
debug(work, '[~w] Start working ~w sec', [Me, N]),
r(N, E),
thread_send_message(Sender, done(E)),
worker
; true
).
r(N, E) :-
catch(call_with_time_limit(N, (repeat, fail)),
E, true).
w(N) :-
alarm(N, writeln(hello), Id),
writeln(Id).
/*******************************
* FLOODING *
*******************************/
:- dynamic
x/1.
flood_test :-
retractall(x(_)),
forall(between(1, 100, X),
alarm(1, got(X), _,
[ remove(true)
])),
get_time(Now),
repeat,
get_time(End),
End - Now > 2, !,
( forall(between(1, 100, X), x(X))
-> retractall(x(_))
; forall(between(1, 100, X),
( x(X)
-> true
; format('Failed: ~D~n', [X])
))
).
got(X) :-
assert(x(X)).
/*******************************
* DEBUG *
*******************************/
list_alarms :-
( current_alarm(At, Callable, Id, Status),
format('~p ~p ~p ~p~n', [At, Callable, Id, Status]),
fail
; true
).