Skip to content

Instantly share code, notes, and snippets.

@danielkraic
Last active April 10, 2017 05:06
Show Gist options
  • Save danielkraic/9e8462c087e214f4417ee90516a535f4 to your computer and use it in GitHub Desktop.
Save danielkraic/9e8462c087e214f4417ee90516a535f4 to your computer and use it in GitHub Desktop.
solution to 'Enhancing the frequency server' - week 1 assignment of futurelearn's Concurrent programming Erlang
%% 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([start/0,allocate/0,deallocate/1,stop/0,clear/0]).
-export([init/0]).
%% These are the start functions used to create and
%% initialize the server.
start() ->
register(frequency,
spawn(frequency, init, [])).
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} ->
timer:sleep(1000),
{NewFrequencies, Reply} = allocate(Frequencies, Pid),
Pid ! {reply, Reply},
loop(NewFrequencies);
{request, Pid , {deallocate, Freq}} ->
% timer:sleep(1000),
{NewFrequencies, Reply} = deallocate(Frequencies, Freq),
Pid ! {reply, Reply},
loop(NewFrequencies);
{request, Pid, stop} ->
Pid ! {reply, stopped}
end.
%% Functional interface
allocate() ->
clear(),
frequency ! {request, self(), allocate},
receive
{reply, Reply} -> Reply
after 1000 ->
{error, timeout}
end.
deallocate(Freq) ->
clear(),
frequency ! {request, self(), {deallocate, Freq}},
receive
{reply, Reply} -> Reply
after 1000 ->
{error, timeout}
end.
stop() ->
clear(),
frequency ! {request, self(), stop},
receive
{reply, Reply} -> Reply
end.
clear() ->
receive
{reply, Reply} ->
io:format("mailbox msg cleared: ~p~n", [Reply]),
clear()
after 0 ->
% terminate if there is no message in mailbox
ok
end.
%% The Internal Help Functions used to allocate and
%% deallocate frequencies.
allocate({[Freq|Free], Allocated}, Pid) ->
AlreadyAllocated = lists:any(fun({_ElFreq, ElPid}) -> ElPid =:= Pid end, Allocated),
case AlreadyAllocated of
true ->
{{[Freq|Free], Allocated}, {error, already_allocated}};
false ->
{{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}
end.
deallocate({Free, Allocated}, Freq) ->
AlreadyAllocated = lists:any(fun({ElFreq, _ElPid}) -> ElFreq =:= Freq end, Allocated),
case AlreadyAllocated of
true ->
NewAllocated = lists:keydelete(Freq, 1, Allocated),
{{[Freq|Free], NewAllocated}, ok};
false ->
{{Free, Allocated}, {error, not_found}}
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment