Advertisement
Guest User

Untitled

a guest
Jun 21st, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 2.89 KB | None | 0 0
  1. -module(lock2).
  2. -export([init/2]).
  3.  
  4. %lock2: Each lock has a unique identifier: 1,2,3,4 which gives the lock a priority.
  5. %change the waiting state so that a lock in the waiting state will send ok to a request
  6. %if this request is coming from a lock with higher priority. If it comes from a lock
  7. %with lower priority, then proceed as in lock1.
  8.  
  9. init(MyId, Nodes) ->    %when the lock is started it is given a unique ID: MyId
  10.     open(Nodes, MyId).
  11.    
  12.  
  13. open(Nodes, MyId) ->
  14.     receive
  15.         {take, Master} ->   %my worker wants the lock
  16.             Refs = requests(Nodes, MyId),   %inform all other locks that i need to be taken
  17.             wait(Nodes, Master, Refs, [], MyId);    %and enter waiting state
  18.         {request, From, Ref, _} ->  %request from another lock
  19.             From ! {ok, Ref},   %immediately reply ok (i'm in open state)
  20.             open(Nodes, MyId);  %and enter open state again
  21.         stop ->
  22.             ok
  23.     end.
  24.  
  25. requests(Nodes, MyId) ->    %send a request message to all locks
  26.     lists:map(fun(P) -> R = make_ref(), P ! {request, self(), R, MyId}, R end, Nodes).  %I send my ID together with the request message.
  27.  
  28. wait(Nodes, Master, [], Waiting, MyId) ->   %waiting state with empty list of locks -- all of the locks sent me an ok message!! -> I can take the lock!
  29.     Master ! taken,     %the lock is taken
  30.     held(Nodes, Waiting, MyId); %enter the held state
  31.  
  32. wait(Nodes, Master, Refs, Waiting, MyId) -> %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} ->
  36.             if
  37.                 MyId > Req_Id ->    %The requesting lock has higher priority
  38.                 From ! {ok, Ref},   %send an ok message to it! 
  39.                 %send another request to the lock with higher priority
  40.                 %to ensure the "happened before" order
  41.                 Ref2 = requests([From], MyId),
  42.                 wait(Nodes, Master, Ref2, Waiting, MyId);   %and enter waiting state
  43.                 % NOT back to open state -> back to WAIT state!!!
  44.            
  45.                 true -> %I have higher priority: I keep the request and I go on :p
  46.                 wait(Nodes, Master, Refs, [{From, Ref}|Waiting], MyId)
  47.             end;
  48.         {ok, Ref} ->    %i received an ok message from a lock
  49.             Refs2 = lists:delete(Ref, Refs),    %and I delete it from my list
  50.             wait(Nodes, Master, Refs2, Waiting, MyId);  %waiting for the rest of the ok messages
  51.         release ->  %I have to release the lock
  52.             ok(Waiting),    %I sent ok messages to the locks that requested me while I was waiting
  53.             open(Nodes, MyId)   %back to open state
  54.     end.
  55.  
  56. ok(Waiting) ->  %send ok message
  57.     lists:map(fun({F,R}) -> F ! {ok, R} end, Waiting).
  58.  
  59. held(Nodes, Waiting, MyId) ->   %The lock is mine!!!
  60.     receive
  61.         {request, From, Ref, _} ->  %I keep on accepting requests from other locks to send them ok afterwards
  62.             held(Nodes, [{From, Ref}|Waiting], MyId);
  63.         release ->  %release message from the worker -> I have to release the lock
  64.             ok(Waiting),    %I inform the waiting locks!
  65.             open(Nodes, MyId)   %back to open state!!
  66.     end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement