Advertisement
Guest User

Untitled

a guest
Jun 21st, 2017
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 3.70 KB | None | 0 0
  1. -module(lock3).
  2. -export([init/3]).
  3.  
  4. %lock3: Each lock has a unique identifier: 1,2,3,4 which gives the lock a priority.
  5. %Use of Lamport clocks to give locks in time priority order.
  6.  
  7. init(MyId, Nodes, MyClock) ->   %when the lock is started it is given a unique ID: MyId
  8.     MyClock = 0,        %The initial value of MyClock is zero
  9.     open(Nodes, MyId, MyClock).
  10.    
  11.  
  12. open(Nodes, MyId, MyClock) ->
  13.     receive
  14.         {take, Master} ->   %my worker wants the lock
  15.             Refs = requests(Nodes, MyId, MyClock),  %inform all other locks that i need to be taken
  16.             wait(Nodes, Master, Refs, [], MyId, MyClock, MyClock);  %and enter waiting state (My current clock and my request clock!!!)
  17.         {request, From, Ref, _, Clock} ->   %request from another lock
  18.             NewClock = lists:max([MyClock, Clock]) + 1, %update MyClock
  19.             From ! {ok, Ref, NewClock}, %immediately reply ok (i'm in open state)
  20.             open(Nodes, MyId, NewClock);    %and enter open state again
  21.         stop ->
  22.             ok
  23.     end.
  24.  
  25. requests(Nodes, MyId, MyClock) ->   %send a request message to all locks
  26.     lists:map(fun(P) -> R = make_ref(), P ! {request, self(), R, MyId, MyClock}, R end, Nodes). %I send my ID together with the request message.
  27.  
  28. wait(Nodes, Master, [], Waiting, MyId, MyClock, _) ->   %waiting state with empty list of locks -- all of the locks sent me an ok message!!
  29.     Master ! taken,     %the lock is taken
  30.     held(Nodes, Waiting, MyId, MyClock);    %enter the held state
  31.  
  32. wait(Nodes, Master, Refs, Waiting, MyId, MyClock, MyReqClock) ->    %waiting for ok messages
  33.     receive
  34.     %prepei na allaksw to format tou mhnymatos request, wste na periexei kai to Id tou lock apo to opoio erxetai to request!!!
  35.         {request, From, Ref, Req_Id, Req_Clock} ->
  36.             NewClock = lists:max([MyClock, Req_Clock]) + 1, %update MyClock
  37.             if
  38.                 MyReqClock > Req_Clock ->   %The requesting lock has higher clock priority
  39.                 From ! {ok, Ref, NewClock}, %send an ok message to it! 
  40.                 % NOT back to open state -> back to WAIT state!!!
  41.                 wait(Nodes, Master, Refs, Waiting, MyId, NewClock, MyReqClock); %and enter waiting state
  42.            
  43.                 MyReqClock == Req_Clock ->  %The req. clock has the same priority as me -> compare process IDs
  44.                 if
  45.                     MyId < Req_Id ->    %The requesting lock has higher priority
  46.                     From ! {ok, Ref, NewClock}, %send an ok message to it! 
  47.                     wait(Nodes, Master, Refs, Waiting, MyId, NewClock, MyReqClock); %and enter waiting state
  48.  
  49.                     true ->
  50.                     wait(Nodes, Master, Refs, [{From, Ref}|Waiting], MyId, NewClock, MyReqClock)
  51.                 end;
  52.                
  53.                 true -> %I have higher priority: I keep the request and I go on :p
  54.                 wait(Nodes, Master, Refs, [{From, Ref}|Waiting], MyId, NewClock, MyReqClock)
  55.             end;
  56.  
  57.         {ok, Ref, Req_Clock2} ->    %i received an ok message from a lock
  58.             NewClock2 = lists:max([MyClock, Req_Clock2]) + 1,   %update MyClock
  59.             Refs2 = lists:delete(Ref, Refs),    %and I delete it from my list
  60.             wait(Nodes, Master, Refs2, Waiting, MyId, NewClock2, MyReqClock);   %waiting for the rest of the ok messages
  61.  
  62.         release ->  %I have to release the lock
  63.             ok(Waiting, MyClock),   %I send ok messages to the locks that requested me while I was waiting
  64.             open(Nodes, MyId, MyClock)  %back to open state
  65.     end.
  66.  
  67. ok(Waiting, MyClock) -> %send ok message
  68.     lists:map(fun({F, R}) -> F ! {ok, R, MyClock} end, Waiting).
  69.  
  70. held(Nodes, Waiting, MyId, MyClock) ->  %The lock is mine!!!
  71.     receive
  72.         {request, From, Ref, _, Req_Clock} ->   %I keep on accepting requests from other locks to send them ok afterwards
  73.             NewClock = lists:max([MyClock, Req_Clock]) + 1, %update MyClock
  74.             held(Nodes, [{From, Ref}|Waiting], MyId, NewClock);
  75.         release ->  %release message from the worker -> I have to release the lock
  76.             ok(Waiting, MyClock),   %I inform the waiting locks!
  77.             open(Nodes, MyId, MyClock)  %back to open state!!
  78.     end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement