Skip to content

Instantly share code, notes, and snippets.

@tclem
Created April 14, 2010 02:15
Show Gist options
  • Select an option

  • Save tclem/365370 to your computer and use it in GitHub Desktop.

Select an option

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

tclem commented Apr 18, 2011

Copy link
Copy Markdown
Author

Love this gist thing.

@tclem

tclem commented Apr 18, 2011

Copy link
Copy Markdown
Author

Just commenting for the sake of commenting

@tclem

tclem commented Apr 18, 2011

Copy link
Copy Markdown
Author

update comment text

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