Skip to content

Instantly share code, notes, and snippets.

@paucus
Created April 6, 2017 22:25
Show Gist options
  • Save paucus/3cc5decf21fce4f8f53be5f98e54efba to your computer and use it in GitHub Desktop.
Save paucus/3cc5decf21fce4f8f53be5f98e54efba to your computer and use it in GitHub Desktop.
%% Based on code from
%% Erlang Programming
%% Francecso Cesarini and Simon Thompson
%% O'Reilly, 2008
%% http://oreilly.com/catalog/9780596518189/
%% http://www.erlangprogramming.org/
%% (c) Francesco Cesarini and Simon Thompson
-module(frequency).
-export([init/0,start/0,stop/0,test_functions/0]).
-include_lib("eunit/include/eunit.hrl").
%% These are the start functions used to create and
%% initialize the server.
init() ->
Frequencies = {get_frequencies(), []},
loop(Frequencies).
% Hard Coded
get_frequencies() -> [10,11,12,13,14,15].
%% The Main Loop
loop(Frequencies) ->
receive
{request, Pid, allocate} ->
{NewFrequencies, Reply} = allocate(Frequencies, Pid),
Pid ! {reply, Reply},
io:format("NewFrequencies is ~w ~n",[NewFrequencies]),
io:format("Reply is ~w ~n",[Reply]),
loop(NewFrequencies);
{request, Pid , {deallocate, Freq}} ->
io:format("Freq is ~w ~n",[Freq]),
{NewFrequencies,Reply} = deallocate(Frequencies, {Freq,Pid}),
Pid ! {reply, Reply},
loop(NewFrequencies);
{request, Pid, stop} ->
Pid ! {reply, stopped},
stopped
end.
%% The Internal Help Functions used to allocate and
%% deallocate frequencies.
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}}; % no free freqs, return error msg
allocate({[Freq|Free], Allocated}=Frequencies, Pid) ->
case lists:keymember(Pid,2,Allocated) of % see if this Pid already has a frecuency (key in 2nd pos)
true -> {Frequencies, {error, already_allocated}}; % will not allocate second freq to same pid
false -> {{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}} % first allocation to this Pid, return rest of frequencies
end.
deallocate({Free, Allocated}, {Freq,Pid}) ->
case lists:member({Freq,Pid}, Allocated) of
true ->
Allocated2 = lists:delete({Freq,Pid}, Allocated), % this Pid did have this freq, so release it
{{[Freq|Free], Allocated2}, ok};
false ->
{{Free, Allocated}, {error, not_allocated}} % whatcha talkin 'bout bro?
end.
start()->
Pid=spawn(frequency,init,[]),
register(?MODULE,Pid),
io:format("Frequency server is ~w ~n",[Pid]),
started.
stop()->
?MODULE ! {request,self(),stop}.
test_functions() -> % by David Ventimiglia
%% Allocate a freq, wait for the reply, print it out.
?MODULE ! {request,self(),allocate},
{ok,F1} = receive {reply,Msg1} -> Msg1 end,
?debugFmt("allocated: ~w~n",[F1]),
   %% Deallocate the freq.  Should succeed.
    ?MODULE ! {request,self(),{deallocate,F1}},
    ok = receive {reply,Msg2} -> Msg2 end,
?debugFmt("deallocated: ~w~n",[Msg2]),
    %% Allocate a freq, wait for the reply, print it out.
    ?MODULE ! {request,self(),allocate},
    {ok,F3} = receive {reply,Msg3} -> Msg3 end,
    ?debugFmt("allocated:  ~w~n",[F3]),
    %% Because we allocated,deallocated,allocated, the two frequencies
    %% should be the same.
    ?assert(F1==F3),
    %% Allocate a freq.  Because we already have an allocation, this
    %% should fail.
    ?MODULE ! {request,self(),allocate},
    {error,already_allocated} = receive {reply,Msg5} -> Msg5 end,
    %% Deallocate the freq that we have.  This should succeed the
    %% first time.
    ?MODULE ! {request,self(),{deallocate,10}},
    ok = receive {reply,Msg6} -> Msg6 end,
    %% Now, deallocate a freq for which we no longer have a lease.
    %% This should fail.
    ?MODULE ! {request,self(),{deallocate,10}},
    {error,not_allocated} = receive {reply,Msg7} -> Msg7 end
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment