syndicate-java/src/test/erlang/ring.erl

57 lines
1.6 KiB
Erlang
Raw Normal View History

-module(ring).
%% erlc ring.erl; erl +P 10000000 -eval 'io:format("~p~n", [ring:start(1000000, 1000)]), init:stop()'
-export([start/2]).
start(NActors, NRounds) ->
io:format("Starting threads...~n"),
First = spawn1(NRounds),
Peers = [Last | _] = spawnN(NActors - 1, [First], NRounds),
First ! {peer, Last},
io:format("Starting measurement (~p processes)...~n", [length(Peers)]),
{Microseconds, ok} =
timer:tc(fun () ->
[P ! {hop, 0} || P <- Peers],
wait_for_all(NActors)
end),
Seconds = Microseconds / 1000000.0,
{ok, {{seconds, Seconds}, {hz, NActors * NRounds / Seconds}}}.
wait_for_all(0) ->
ok;
wait_for_all(Remaining) ->
receive
one_actor_done ->
wait_for_all(Remaining - 1)
end.
spawn1(NRounds) ->
Main = self(),
spawn(fun () -> forwarder_main(Main, NRounds) end).
spawnN(0, Peers, _NRounds) ->
Peers;
spawnN(Remaining, Peers = [Peer | _], NRounds) ->
A = spawn1(NRounds),
A ! {peer, Peer},
spawnN(Remaining - 1, [A | Peers], NRounds).
forwarder_main(MainActor, NRounds) ->
receive
{peer, Peer} ->
forwarder_main_loop(MainActor, Peer, NRounds)
end.
forwarder_main_loop(MainActor, Peer, NRounds) ->
receive
{hop, HopCount} ->
if
HopCount < NRounds - 1 ->
Peer ! {hop, HopCount + 1};
true ->
MainActor ! one_actor_done
end,
forwarder_main_loop(MainActor, Peer, NRounds)
end.