Skip to content

@ferd /race.erl
Last active

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
#!/usr/bin/env escript
%% -*- erlang -*-
%%! +P 100000000
-module(race).
-mode(compile).
-export([main/1]).
main(Args) ->
[NumThreads, NumRunners] = [list_to_integer(Arg) || Arg <- Args],
Parent = self(),
RacerA = spawn_link(fun() -> race(Parent, NumRunners, NumThreads) end),
RacerB = spawn_link(fun() -> race(Parent, NumRunners, NumThreads) end),
receive
{RacerA, Res} ->
io:format("A won: ~p~n", [Res]);
{RacerB, Res} ->
io:format("B won: ~p~n", [Res])
end,
halt(0).
race(Parent, NumRunners, NumThreads) ->
io:format("making tracks~n"),
First = make_tracks(self(), 0, NumThreads),
io:format("sending runners~n"),
send_runners(First, NumRunners),
io:format("waiting for finishers~n"),
Parent ! {self(), recv_runners(NumRunners)}.
make_tracks(Parent, 0, N) ->
Pid = spawn_link(fun() -> last_track(Parent) end),
make_tracks(Pid, 1, N);
make_tracks(Parent, N, N) ->
spawn_link(fun() -> track(Parent) end);
make_tracks(Parent, N, Max) ->
Pid = spawn_link(fun() -> track(Parent) end),
make_tracks(Pid, N+1, Max).
send_runners(_, 0) -> ok;
send_runners(Pid, N) ->
Pid ! {from, self(), N},
send_runners(Pid, N-1).
track(To) ->
receive
{from, Parent, N} ->
To ! {from, self(), N},
track(To, Parent)
end.
track(To, Parent) ->
receive
{from, Parent, N} -> To ! {from, self(), N};
{back, N} -> Parent ! {back, N}
end,
track(To, Parent).
last_track(To) ->
receive
{from, Parent, N} -> Parent ! {back, N}
end,
last_track(To).
recv_runners(N) -> recv_runners(N,[]).
recv_runners(0, Acc) -> lists:reverse(Acc);
recv_runners(N, Acc) ->
receive
{back, Runner} -> recv_runners(N-1, [Runner|Acc])
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.