4
%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
6
%% The contents of this file are subject to the Erlang Public License,
7
%% Version 1.1, (the "License"); you may not use this file except in
8
%% compliance with the License. You should have received a copy of the
9
%% Erlang Public License along with this software. If not, it can be
10
%% retrieved online at http://www.erlang.org/.
12
%% Software distributed under the License is distributed on an "AS IS"
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14
%% the License for the specific language governing rights and limitations
20
-module(save_calls_SUITE).
22
-include("test_server.hrl").
26
-export([save_calls_1/1,dont_break_reductions/1]).
28
-export([do_bopp/1, do_bipp/0, do_bepp/0]).
31
[save_calls_1, dont_break_reductions].
33
dont_break_reductions(suite) ->
35
dont_break_reductions(doc) ->
36
["Check that save_calls dont break reduction-based scheduling"];
37
dont_break_reductions(Config) when is_list(Config) ->
38
?line RPS1 = reds_per_sched(0),
39
?line RPS2 = reds_per_sched(20),
40
?line Diff = abs(RPS1 - RPS2),
41
?line true = (Diff < (0.05 * RPS1)),
45
reds_per_sched(SaveCalls) ->
46
?line Parent = self(),
47
?line HowMany = 10000,
48
?line Pid = spawn(fun() ->
49
process_flag(save_calls,SaveCalls),
52
carmichaels_below(HowMany),
53
Parent ! erlang:process_info(self(),reductions)
56
?line TH = spawn(fun() -> trace_handler(0,Parent,Pid) end),
57
?line erlang:trace(Pid, true,[running,procs,{tracer,TH}]),
59
?line {Sched,Reds} = receive
61
receive {reductions,Y} ->
73
trace_handler(Acc,Parent,Client) ->
75
{trace,Client,out,_} ->
76
trace_handler(Acc+1,Parent,Client);
77
{trace,Client,exit,_} ->
78
Parent ! {accumulated, Acc};
80
trace_handler(Acc,Parent,Client)
85
save_calls_1(doc) -> "Test call saving.";
86
save_calls_1(Config) when is_list(Config) ->
87
case test_server:is_native(?MODULE) of
88
true -> {skipped,"Native code"};
89
false -> save_calls_1()
93
?line erlang:process_flag(self(), save_calls, 0),
94
?line {last_calls, false} = process_info(self(), last_calls),
96
?line erlang:process_flag(self(), save_calls, 10),
97
?line {last_calls, _L1} = process_info(self(), last_calls),
98
?line ?MODULE:do_bipp(),
99
?line {last_calls, L2} = process_info(self(), last_calls),
100
?line L21 = lists:filter(fun is_local_function/1, L2),
102
[{?MODULE,do_bipp,0},
108
{?MODULE,do_bepp,0}] ->
111
test_server:fail({l21, X})
114
?line erlang:process_flag(self(), save_calls, 10),
115
?line {last_calls, L3} = process_info(self(), last_calls),
116
?line L31 = lists:filter(fun is_local_function/1, L3),
125
apply(?MODULE, do_bepp, []).
139
is_local_function({?MODULE, _, _}) ->
141
is_local_function({_, _, _}) ->
143
is_local_function(_) ->
147
% Number crunching for reds test.
148
carmichaels_below(N) ->
149
random:seed(3172,9814,20125),
150
carmichaels_below(1,N).
152
carmichaels_below(N,N2) when N >= N2 ->
154
carmichaels_below(N,N2) ->
155
X = case fast_prime(N,10) of
158
case fast_prime2(N,10) of
160
%io:format("Prime: ~p~n",[N]),
163
io:format("Carmichael: ~p (dividable by ~p)~n",
164
[N,smallest_divisor(N)]),
168
X+carmichaels_below(N+2,N2).
170
expmod(_,E,_) when E == 0 ->
172
expmod(Base,Exp,Mod) when (Exp rem 2) == 0 ->
173
X = expmod(Base,Exp div 2,Mod),
175
expmod(Base,Exp,Mod) ->
176
(Base * expmod(Base,Exp - 1,Mod)) rem Mod.
185
do_fast_prime(1,_) ->
187
do_fast_prime(_N,0) ->
189
do_fast_prime(N,Times) ->
192
do_fast_prime(N,Times-1);
200
expmod2(_,E,_) when E == 0 ->
202
expmod2(Base,Exp,Mod) when (Exp rem 2) == 0 ->
203
%% Uncomment the code below to simulate scheduling bug!
204
% case erlang:process_info(self(),last_calls) of
205
% {last_calls,false} -> ok;
206
% _ -> erlang:yield()
208
X = expmod2(Base,Exp div 2,Mod),
211
Y == 1, X =/= 1, X =/= (Mod - 1) ->
216
expmod2(Base,Exp,Mod) ->
217
(Base * expmod2(Base,Exp - 1,Mod)) rem Mod.
223
do_fast_prime2(1,_) ->
225
do_fast_prime2(_N,0) ->
227
do_fast_prime2(N,Times) ->
228
case miller_rabbin(N) of
230
do_fast_prime2(N,Times-1);
238
smallest_divisor(N) ->
241
find_divisor(N,TD) ->
246
case divides(TD,N) of