Advertisement
Guest User

Untitled

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