Skip to content

Instantly share code, notes, and snippets.

@codeholic
Created July 26, 2010 19:12
Show Gist options
  • Select an option

  • Save codeholic/491064 to your computer and use it in GitHub Desktop.

Select an option

Save codeholic/491064 to your computer and use it in GitHub Desktop.
% Write a ring benchmark. Create N processes in a ring. Send a message
% round the ring M times so that a total of N * M messages get sent.
% Time how long this takes for different values of N and M.
% -- Joe Armstrong, "Programming Erlang"
% Copyright (c) 2008-2010 Ivan Fomichev
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the "Software"), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
% copies of the Software, and to permit persons to whom the Software is
% furnished to do so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in
% all copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
% THE SOFTWARE.
% SYNOPSIS
%
% R = ring:new(5, verbose), R ! {self(), {message, 3, hello}}.
%
% Start = now(),
% R2 = ring:new(10000),
% R2 ! {self(), {message, 10000000, hello}},
% End = now(),
% timer:now_diff(End, Start) / 1000000.
-module(ring).
-export([new/1,new/2]).
report(verbose, Format, Params) ->
io:format(Format, Params);
report(quiet, _, _) -> ok.
new(N) -> new(N, quiet).
new(N, Verbose) when N >= 1 ->
First = spawn(fun() -> loop(none, Verbose) end),
report(Verbose, "~p says: new ~p~n", [self(), First]),
Last = new(2, N, First, Verbose),
First ! {self(), {sends_to, Last}},
First.
new(I, N, SendsTo, Verbose) when I =< N ->
Pid = spawn(fun() -> loop(SendsTo, Verbose) end),
report(Verbose, "~p says: new ~p sends messages to ~p~n", [self(), Pid, SendsTo]),
new(I+1, N, Pid, Verbose);
new(_, _, Pid, _) -> Pid.
loop(SendsTo, Verbose) ->
Self = self(),
receive
{_, {sends_to, Pid}} ->
report(Verbose, "~p says: ~p sends messages to ~p~n", [Self, Self, Pid]),
loop(Pid, Verbose);
{From, {message, M, Message}} ->
report(Verbose, "~p got ~p from ~p, more ~p laps~n", [Self, Message, From, M]),
SendsTo ! {Self, {pass, Self, M, Message}},
loop(SendsTo, Verbose);
{From, {pass, Self, 1, Message}} ->
report(Verbose, "~p got ~p from ~p, quit~n", [Self, Message, From]),
loop(SendsTo, Verbose);
{From, {pass, Self, M, Message}} ->
report(Verbose, "~p got ~p from ~p, more ~p laps~n", [Self, Message, From, M-1]),
SendsTo ! {Self, {pass, Self, M-1, Message}},
loop(SendsTo, Verbose);
{From, {pass, Origin, M, Message}} ->
report(Verbose, "~p got ~p from ~p~n", [Self, Message, From]),
SendsTo ! {Self, {pass, Origin, M, Message}},
loop(SendsTo, Verbose)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment