Skip to content

Instantly share code, notes, and snippets.

@tecnowilliam
Last active June 29, 2020 18:52
Show Gist options
  • Select an option

  • Save tecnowilliam/6fc6cb622fd029a08408c607f85d4e05 to your computer and use it in GitHub Desktop.

Select an option

Save tecnowilliam/6fc6cb622fd029a08408c607f85d4e05 to your computer and use it in GitHub Desktop.
% Compile: c(frequency).
-module(frequency).
-author("William Vargas").
-version("1.0").
-export([init/0, start/0, allocate/0, deallocate/1, tests/0]).
% Register the server as frequency
-spec start() -> frequency.
start() ->
register(frequency, spawn(frequency, init, [])).
% Initialize the server
-spec init() -> any().
init() ->
Frequencies = {get_frequencies(), []},
io:format("Server started~n"),
loop(Frequencies).
% Get the frequencies
-spec get_frequencies() -> list(integer()).
get_frequencies() -> [10,11,12,13,14,15].
% Process the server messages
-spec loop(list(integer())) -> any().
loop(Frequencies) ->
receive
{request, Pid, allocate} ->
{NewFrequencies, Reply} = allocate(Frequencies, Pid),
Pid ! {reply, Reply},
loop(NewFrequencies);
{request, Pid , {deallocate, Freq}} ->
NewFrequencies = deallocate(Frequencies, Freq),
Pid ! {reply, {ok, -Freq}},
loop(NewFrequencies);
{request, _Pid, overload} ->
timer:sleep(1000),
loop(Frequencies);
{request, Pid, stop} ->
Pid ! {reply, stopped}
end.
% Functional interface: allocate
-spec allocate() -> any().
allocate() ->
frequency ! {request, self(), allocate},
receive
{reply, Reply} ->
io:format("~w~n",[Reply]),
Reply
after 1000 ->
clear(),
timeout
end.
% Allocate a frequency
-spec allocate(list(), pid()) -> tuple().
allocate({[], Allocated}, _Pid) ->
{{[], Allocated}, {error, no_frequency}};
allocate({[Freq|Free], Allocated}, Pid) ->
{{Free, [{Freq, Pid}|Allocated]}, {ok, Freq}}.
% Functional interface: deallocate
-spec deallocate(integer()) -> any().
deallocate(Freq) ->
frequency ! {request, self(), {deallocate, Freq}},
receive
{reply, Reply} ->
io:format("~w~n",[Reply]),
Reply
after 1000 ->
clear(),
timeout
end.
% Deallocate a frequency
-spec deallocate(tuple(), integer()) -> tuple().
deallocate({Free, Allocated}, Freq) ->
case lists:keymember(Freq, 1, Allocated) of
true ->
NewAllocated = lists:keydelete(Freq, 1, Allocated),
{[Freq|Free], NewAllocated};
_ ->
{Free, Allocated}
end.
% Clear all the mailbox
-spec clear() -> ok.
clear() ->
receive
_Msg -> clear()
after 0 ->
io:format("Mailbox cleared~n"),
ok
end.
-spec tests() -> any().
tests() ->
% Test: Clean mailbox
clear(),
% Test: Start server
start(),
% Test: Allocate 10,11 and 12
allocate(), allocate(), allocate(),
% Test: Deallocate 11
deallocate(11),
% Test: Allocate 11 and 13
allocate(), allocate(),
% Test: Overloaded server
frequency ! {request, self(), overload},
allocate().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment