Skip to content

Instantly share code, notes, and snippets.

@tclem
Created April 14, 2010 02:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tclem/365370 to your computer and use it in GitHub Desktop.
Save tclem/365370 to your computer and use it in GitHub Desktop.
using System.Diagnostics;
using System.Threading;
namespace ErlanCompetition
{
internal class Program
{
#region private
private static void Main()
{
const int n = 2000;
const int r = 10;
Trace.WriteLine(string.Format("Creating proc ring with {0} node(s)", n));
Trace.WriteLine(string.Format("Passing message around {0} time(s)", r));
var masterNode = new MasterNode();
masterNode.Start(n, r);
masterNode.WaitForFinish();
}
#endregion
}
public class MasterNode : Node
{
#region Fields
private readonly AutoResetEvent finishResetEvent = new AutoResetEvent(false);
private int count;
private Node firstNode;
private int rounds;
private Stopwatch stopwatch;
#endregion
#region public
public void Start(int n, int r)
{
rounds = r;
stopwatch = Stopwatch.StartNew();
thread = new Thread(Loop);
thread.Start();
firstNode = new Node(this, 1, n);
firstNode.SendMessage(Action.PassMessage);
}
public void WaitForFinish()
{
finishResetEvent.WaitOne();
}
#endregion
#region protected
protected override void Loop()
{
while (run)
{
resetEvent.WaitOne();
if (action == Action.Die)
{
run = false;
Trace.WriteLine(string.Format("Took {0}.", stopwatch.Elapsed));
finishResetEvent.Set();
return;
}
count++;
firstNode.SendMessage(count < rounds ? Action.PassMessage : Action.Die);
}
}
#endregion
}
public class Node
{
#region Fields
protected readonly AutoResetEvent resetEvent = new AutoResetEvent(false);
protected Action action;
private Node nextNode;
protected volatile bool run = true;
protected Thread thread;
#endregion
#region Constructors
public Node()
{
}
public Node(MasterNode master, int id, int total)
{
thread = new Thread(
() =>
{
nextNode = id == total ? master : new Node(master, id + 1, total);
Loop();
});
thread.Start();
}
#endregion
#region public
public void SendMessage(Action a)
{
action = a;
resetEvent.Set();
}
#endregion
#region protected
protected virtual void Loop()
{
while (run)
{
resetEvent.WaitOne();
nextNode.SendMessage(action);
if (action == Action.Die) run = false;
}
}
#endregion
}
public enum Action
{
PassMessage,
Die,
}
}
-module(ring).
-export([start/2]).
start(N, Rounds) ->
io:format("Creating proc ring with ~p node(s)~n", [N]),
io:format("Passing message around ~p time(s)~n", [Rounds]),
Pid = self(),
statistics(wall_clock),
H = spawn(fun() -> loop(Pid, 1, N) end),
H ! {pass, 1, Rounds},
master(H),
{_, Time} = statistics(wall_clock),
io:format("Took ~p milliseconds~n",[Time]).
master(H) ->
receive
{pass, T, T} ->
H ! die;
%io:format("Round ~p of ~p finished~n", [T, T]);
{pass, C, T} ->
%io:format("Round ~p of ~p finished~n", [C, T]),
H ! {pass, C+1, T},
master(H)
end.
loop(MasterPid, N, N) ->
bounce(MasterPid);
loop(MasterPid, I, N) ->
NextPid = spawn(fun() -> loop(MasterPid, I+1, N) end),
bounce(NextPid).
bounce(Pid) ->
receive
{pass, C, Msg} ->
Pid ! {pass, C, Msg},
bounce(Pid);
die ->
Pid ! die
end.
@tclem
Copy link
Author

tclem commented Apr 18, 2011

Love this gist thing.

@tclem
Copy link
Author

tclem commented Apr 18, 2011

Just commenting for the sake of commenting

@tclem
Copy link
Author

tclem commented Apr 18, 2011

update comment text

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment