Labels

Sunday, May 3, 2009

Programming Erlang - Exercise 8.11.2 MM#1 Code

(MM#1 algorithm)-module(c8p2m_t1).
-export([c8_ping/2,c8_loop/1
]).
%%-----------------------------* CREATE the RING *--------------------------------------------------------
c8_ping(N,M) when is_integer(N), is_integer(M), N > 1 ->

Max = erlang:system_info(process_limit),
TotalMsgCnt = N*M,
StartP = spawn(?MODULE, c8_loop, [[self(), TotalMsgCnt]]), %%--- START process pid of the RING
case (N > Max) of
true ->
EndP = c8_for(1, Max, StartP, TotalMsgCnt ); %%--- END process pid of the RING
false ->
EndP = c8_for(1, N, StartP, TotalMsgCnt) %%--- END process pid of the RING
end,
StartP ! EndP, %%--- Initiate the ping process
io:format(" Max number of processes: ~p / Ring size: ~p processes / Number of circles: ~p~n", [Max,N,M]).
%%-----------------------------* CREATE the RING *--------------------------------------------------------

%%-----------------------------* RING PROCESS *-----------------------------------------------------------
c8_loop([NextPid,TotalMsgCount])->
receive
{ping,CurrentMsgCount}-> %%--- Circle the RING until the total message count is reached!
case (CurrentMsgCount+1) > TotalMsgCount of
true ->
{_,E_time} = statistics(wall_clock),
io:format(" Circling \"ping\" ~p times from process to process in the ring took ~p seconds~n", [CurrentMsgCount, E_time/1000]),
io:format(" Average ping message elapsed time:~p in miliseconds~n", [E_time/CurrentMsgCount]),
NextPid ! die; %%--- housekeeping - start killing all ring processes!
false ->
NextPid ! {ping,CurrentMsgCount+1} %%--- ping the message to the next process in the ring!
end,
c8_loop([NextPid,TotalMsgCount]);
die -> %%--- kill the ring process!
case erlang:is_process_alive(NextPid) of
true ->
NextPid ! die,
c8_flush_buff(),
void;
false ->
c8_flush_buff(),
void,
io:format("* Housekeeping complete: ALL processes assigned to the ring are destroyed! * ~n"),
io:format("__________________________________________________________________________________________~n")
end;
EndP -> %%--- FIRST time to close the RING: link StartP with EndP !
statistics(wall_clock), %%--- Start elapsed time measurements
EndP ! {ping,1}, %%--- Start the first ping around the ring!
c8_loop([EndP,TotalMsgCount])
end.
%%-----------------------------* RING PROCESS *-----------------------------------------------------------

%%-----------------------------* start HELPER FUNCTIONS *-------------------------------------------------
c8_for(N, N, P, _TotalMsgCnt) -> P;
c8_for(I, N, P, _TotalMsgCnt) -> c8_for(I+1, N, spawn(?MODULE, c8_loop, [[P,_TotalMsgCnt]]), _TotalMsgCnt).

c8_flush_buff()->
receive
_Any ->
c8_flush_buff()
after 0 ->
true
end.
%%-----------------------------* end HELPER FUNCTIONS *---------------------------------------------------

No comments:

Post a Comment