diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58bd7f5..e2e850e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,5 +16,5 @@ jobs: run: | rebar3 dialyzer rebar3 eunit -v - rebar3 proper -c true --module prop_boolean,prop_create,prop_manipulating,prop_sorting,prop_db,prop_echo,prop_positive_echo + rebar3 proper -c true --module prop_boolean,prop_create,prop_manipulating,prop_sorting,prop_db,prop_echo,prop_positive_echo,prop_ring # rebar3 cover -m 100 diff --git a/apps/08-anillo-de-procesos/src/ring.erl b/apps/08-anillo-de-procesos/src/ring.erl index 0da46e1..4cdff2c 100644 --- a/apps/08-anillo-de-procesos/src/ring.erl +++ b/apps/08-anillo-de-procesos/src/ring.erl @@ -2,11 +2,47 @@ % Public API -export([start/3]). +-export([init/4, loop/2]). %%-------------------------------------------------------------------- %% @doc Start function. %% @spec start(ProcNum :: pos_integer(), MsgNum :: pos_integer(), Message :: term()) -> ok %% @end %%-------------------------------------------------------------------- -start(_ProcNum, _MsgNum, _Message) -> - erlang:throw(not_implemented). +start(ProcNum, MsgNum, Message) -> + register(master, spawn(?MODULE, init, [ProcNum, MsgNum, Message, self()])), + receive + ring_close -> + ok + end. + +%%%------------------------------------------------------------------- +%%% INTERNAL FUNCTIONS +%%%------------------------------------------------------------------- +init(0, _MsgNum, _Message, _From)-> + ok; +init(1, MsgNum, Message, From) -> + master ! {MsgNum - 1, Message}, + loop(master, From); +init(ProcNum, MsgNum, Message, From) -> + Next = spawn(?MODULE, init, [ProcNum - 1, MsgNum, Message, From]), + loop(Next, From). + +loop(finish, From) -> + receive + stop -> + From ! ring_close + end; +loop(Next, From) -> + receive + {0, Message} -> + io:format("~p~n", [Message]), + Next ! stop, + loop(finish, From); + {MsgNum, Message} -> + io:format("~p~n", [Message]), + Next ! {MsgNum - 1, Message}, + loop(Next, From); + stop -> + Next ! stop + end. diff --git a/apps/08-anillo-de-procesos/test/prop_ring.erl b/apps/08-anillo-de-procesos/test/prop_ring.erl index 1aa0ece..b1c3e5e 100644 --- a/apps/08-anillo-de-procesos/test/prop_ring.erl +++ b/apps/08-anillo-de-procesos/test/prop_ring.erl @@ -49,7 +49,7 @@ prop_ring() -> %% Sub-propiedades % (1) Comprobamos que se crean tantos procesos como se indica creacion(NProcs, Trazas) -> - ParentsAndChildren = [{Parent, Child} || {trace, Parent, spawn, Child, _Fun} <- Trazas], + ParentsAndChildren = [{Parent, Child} || {trace, Parent, spawn, Child, {ring, _, _}} <- Trazas], length(ParentsAndChildren) == NProcs. % (2) Comprobamos que se envía a mensaxe o número de veces axeitado @@ -64,9 +64,10 @@ recepcion(NMsgs, Msg, Trazas) -> % (4) Comprobamos que se destrúen os procesos destruccion(NProcs, Trazas) -> + RingProcs = [Child || {trace, _Parent, spawn, Child, {ring, _, _}} <- Trazas], Stoppers = [{From, To} || {trace, From, send, stop, To} <- Trazas], Stopped = [Who || {trace, Who, 'receive', stop} <- Trazas], - Exited = [Who || {trace, Who, exit, normal} <- Trazas], + Exited = [Who || {trace, Who, exit, normal} <- Trazas, lists:member(Who, RingProcs)], (length(Stoppers) == length(Stopped)) andalso (length(Exited) == NProcs). % Outras posibles sub-propiedades: