Current section
Files
Jump to
Current section
Files
src/timer_wheel/timer_wheel.erl
%% ``The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved via the world wide web at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
%% AB. All Rights Reserved.''
%%
%%
%% File: timer_wheel.erl
%% Author: Björn-Egil Dahlberg
%% Date: 2010-09-10
%%
-module(timer_wheel).
-export([bench_args/2, run/3]).
-export([wheel/1,no_wheel/1]).
bench_args(Version, Conf) ->
{_,Cores} = lists:keyfind(number_of_cores, 1, Conf),
F = case Version of
short -> 16;
intermediate -> 40;
long -> 125
end,
[[Wheel,N] || Wheel <- [wheel,no_wheel], N <- [F * Cores]].
run([wheel,N|_], _, _) ->
test(N, fun recv_loop_after/2);
run([no_wheel,N|_], _, _) ->
test(N, fun recv_loop/2).
wheel(N) ->
test(N, fun recv_loop_after/2).
no_wheel(N) ->
test(N, fun recv_loop/2).
test(N, Fun) ->
Me = self(),
Pids = [spawn_link(fun() -> handler(N - 1, Fun, Me) end) || _ <- lists:seq(1, N)],
[Pid ! {init, Pids -- [Pid]} || Pid <- Pids],
[Pid ! start || Pid <- Pids],
[receive {Pid, done} -> ok end || Pid <- Pids],
ok.
handler(N, Fun, Me) ->
Others = receive {init, Pids} -> Pids end,
receive start -> ok end,
loop(Others, N, Fun, Me).
loop([], 0, _, Me) ->
Me ! {self(), done};
loop([], N, Fun, Me) ->
loop([], Fun(undefined, N), Fun, Me);
loop([Pid|Pids], N, Fun, Me) ->
Pid ! {self(), ping},
loop(Pids, Fun(Pid, N), Fun, Me).
recv_loop_after(_, 0) ->
0;
recv_loop_after(Pid, N) ->
receive
{Pid, pong} -> N;
{Other, ping} -> Other ! {self(), pong},
recv_loop_after(Pid, N - 1)
after 1073741824 -> exit(self(), kill)
end.
recv_loop(_, 0) ->
0;
recv_loop(Pid, N) ->
receive
{Pid, pong} -> N;
{Other, ping} -> Other ! {self(), pong},
recv_loop(Pid, N - 1)
end.