tags:

views:

89

answers:

1

i found example of mutex in erlang

Can somebody modify it to use it with count like semaphore?

-module(mutex). 
-export([start/0, stop/0]). 
-export([wait/0, signal/0]). 
-export([init/0]). 

start() -> 
   register(mutex, spawn(?MODULE, init, [])). 

stop() -> 
   mutex ! stop. 

wait() -> 
   mutex ! {wait, self()}, 
   receive ok -> ok end. 

signal() -> 
   mutex ! {signal, self()}, 
   ok. 

init() -> 
   free(). 

free() -> 
   receive 
      {wait, Pid} -> 
         Pid ! ok, 
         busy(Pid); 
      stop -> 
         terminate() 
   end. 

busy(Pid) -> 
   receive 
      {signal, Pid} -> 
         free() 
   end. 

terminate() -> 
   receive 
      {wait, Pid} -> 
         exit(Pid, kill), 
         terminate() 
   after 
      0 -> ok 
   end.
A: 

Thats not the best semaphore.. could use some random stuff, but hopefully you will get the idea.

-module(sem1).
-export([semaphor/2, start/1, start/0]).

semaphor(0,0) ->
    io:format("err");

semaphor(0,Full)->
    receive
        {increment,PID} ->
            io:format("UP ~w ~w~n", [0,PID]),
            PID ! {incGranted},
            semaphor(1,Full)
    end;


semaphor(Full,Full)->
    receive
        {decrement,PID} ->
            io:format("DOWN ~w ~w~n", [Full,PID]),
            PID ! {decGranted},
            semaphor(Full -1 , Full)
    end;

semaphor(N,Full)->
    receive
        {decrement,PID} ->
            io:format("DOWN ~w ~w~n", [N,PID]),
            PID ! {decGranted},
            semaphor(N -1 , Full);
        {increment,PID} ->
            io:format("UP ~w ~w~n", [N,PID]),
            PID ! {incGranted},
            semaphor(N + 1 , Full)
    end.

start(PID) ->
    PID ! {decrement, self()},
    receive
        {decGranted} -> true
    end,
    timer:sleep(100),
    PID ! {increment, self()},
    receive
        {incGranted} -> true
    end,
    start(PID).

start() ->
    PID = spawn(sem1, semafor, [1,5]),
    spawn(sem1,start,[PID]),
    spawn(sem1,start,[PID]),
    spawn(sem1,start,[PID]),
    spawn(sem1,start,[PID]),
    spawn(sem1,start,[PID]),
    spawn(sem1,start,[PID]).