aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStavros Aronis <[email protected]>2012-03-29 15:06:47 +0200
committerHenrik Nord <[email protected]>2012-05-21 15:31:23 +0200
commit12b8ce08ece794e677fdd148723fbe0a707bef6f (patch)
tree9e589500617e0bb9c643b3227f36c583d03f29cf
parent5c52ff6b5f10c7bd9ce06cdf607e88035c16e079 (diff)
downloadotp-12b8ce08ece794e677fdd148723fbe0a707bef6f.tar.gz
otp-12b8ce08ece794e677fdd148723fbe0a707bef6f.tar.bz2
otp-12b8ce08ece794e677fdd148723fbe0a707bef6f.zip
Anonymous SCCtoPID ETS table
-rw-r--r--lib/dialyzer/src/dialyzer_coordinator.erl58
-rw-r--r--lib/dialyzer/src/dialyzer_worker.erl16
2 files changed, 40 insertions, 34 deletions
diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl
index b91fc95959..5719132215 100644
--- a/lib/dialyzer/src/dialyzer_coordinator.erl
+++ b/lib/dialyzer/src/dialyzer_coordinator.erl
@@ -32,7 +32,7 @@
-export([wait_activation/0, job_done/3]).
%%% Exports for the typesig and dataflow analysis workers
--export([sccs_to_pids/1, request_activation/1]).
+-export([sccs_to_pids/2, request_activation/1]).
%%% Exports for the compilation workers
-export([get_next_label/2]).
@@ -41,9 +41,11 @@
%%--------------------------------------------------------------------
--define(MAP, dialyzer_coordinator_map).
+-type collector() :: pid().
+-type regulator() :: pid().
+-type scc_to_pid() :: ets:tid() | 'unused'.
--type coordinator() :: {pid(), pid()}. %%opaque
+-type coordinator() :: {collector(), regulator(), scc_to_pid()}. %%opaque
-type timing() :: dialyzer_timing:timing_server().
-type scc() :: [mfa_or_funlbl()].
@@ -79,7 +81,8 @@
result :: result(),
next_label = 0 :: integer(),
init_data :: init_data(),
- regulator :: pid()
+ regulator :: regulator(),
+ scc_to_pid :: scc_to_pid()
}).
-include("dialyzer.hrl").
@@ -102,18 +105,18 @@ parallel_job(Mode, Jobs, InitData, Timing) ->
spawn_jobs(Mode, Jobs, InitData, Timing) ->
Collector = self(),
Regulator = spawn_regulator(),
- Coordinator = {Collector, Regulator},
TypesigOrDataflow = (Mode =:= 'typesig') orelse (Mode =:= 'dataflow'),
- case TypesigOrDataflow of
- true ->
- ?MAP = ets:new(?MAP, [named_table, {read_concurrency, true}]);
- false -> ok
- end,
+ SCCtoPID =
+ case TypesigOrDataflow of
+ true -> ets:new(scc_to_pid, [{read_concurrency, true}]);
+ false -> unused
+ end,
+ Coordinator = {Collector, Regulator, SCCtoPID},
Fold =
fun(Job, Count) ->
Pid = dialyzer_worker:launch(Mode, Job, InitData, Coordinator),
case TypesigOrDataflow of
- true -> true = ets:insert(?MAP, {Job, Pid});
+ true -> true = ets:insert(SCCtoPID, {Job, Pid});
false -> request_activation(Regulator, Pid)
end,
Count + 1
@@ -131,11 +134,11 @@ spawn_jobs(Mode, Jobs, InitData, Timing) ->
_ -> []
end,
#state{mode = Mode, active = JobCount, result = InitResult, next_label = 0,
- init_data = InitData, regulator = Regulator}.
+ init_data = InitData, regulator = Regulator, scc_to_pid = SCCtoPID}.
collect_result(#state{mode = Mode, active = Active, result = Result,
next_label = NextLabel, init_data = InitData,
- regulator = Regulator} = State) ->
+ regulator = Regulator, scc_to_pid = SCCtoPID} = State) ->
receive
{next_label_request, Estimation, Pid} ->
Pid ! {next_label_reply, NextLabel},
@@ -149,7 +152,7 @@ collect_result(#state{mode = Mode, active = Active, result = Result,
'compile' ->
{NewResult, NextLabel};
X when X =:= 'typesig'; X =:= 'dataflow' ->
- ets:delete(?MAP),
+ ets:delete(SCCtoPID),
NewResult;
'warnings' ->
NewResult
@@ -170,29 +173,30 @@ update_result(Mode, InitData, Job, Data, Result) ->
Data ++ Result
end.
--spec sccs_to_pids([scc() | module()]) ->
+-spec sccs_to_pids([scc() | module()], coordinator()) ->
{[dialyzer_worker:worker()], [scc() | module()]}.
-sccs_to_pids(SCCs) ->
- lists:foldl(fun pid_partition/2, {[], []}, SCCs).
-
-pid_partition(SCC, {Pids, Unknown}) ->
- try ets:lookup_element(?MAP, SCC, 2) of
- Result -> {[Result|Pids], Unknown}
- catch
- _:_ -> {Pids, [SCC|Unknown]}
- end.
+sccs_to_pids(SCCs, {_Collector, _Regulator, SCCtoPID}) ->
+ Fold =
+ fun(SCC, {Pids, Unknown}) ->
+ try ets:lookup_element(SCCtoPID, SCC, 2) of
+ Result -> {[Result|Pids], Unknown}
+ catch
+ _:_ -> {Pids, [SCC|Unknown]}
+ end
+ end,
+ lists:foldl(Fold, {[], []}, SCCs).
-spec job_done(job(), job_result(), coordinator()) -> ok.
-job_done(Job, Result, {Collector, Regulator}) ->
+job_done(Job, Result, {Collector, Regulator, _SCCtoPID}) ->
Regulator ! done,
Collector ! {done, Job, Result},
ok.
-spec get_next_label(integer(), coordinator()) -> integer().
-get_next_label(EstimatedSize, {Collector, _Regulator}) ->
+get_next_label(EstimatedSize, {Collector, _Regulator, _SCCtoPID}) ->
Collector ! {next_label_request, EstimatedSize, self()},
receive
{next_label_reply, NextLabel} -> NextLabel
@@ -208,7 +212,7 @@ activate_pid(Pid) ->
-spec request_activation(coordinator()) -> ok.
-request_activation({_Collector, Regulator}) ->
+request_activation({_Collector, Regulator, _SCCtoPID}) ->
Regulator ! {req, self()},
wait_activation().
diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl
index cccf1d144b..50b2e31ed8 100644
--- a/lib/dialyzer/src/dialyzer_worker.erl
+++ b/lib/dialyzer/src/dialyzer_worker.erl
@@ -111,25 +111,27 @@ loop(running, #state{mode = Mode} = State) when
waits_more_success_typings(#state{depends_on = Depends}) ->
Depends =/= [].
-broadcast_done(#state{job = SCC, init_data = InitData}) ->
+broadcast_done(#state{job = SCC, init_data = InitData,
+ coordinator = Coordinator}) ->
RequiredBy = dialyzer_succ_typings:find_required_by(SCC, InitData),
- {Callers, Unknown} = dialyzer_coordinator:sccs_to_pids(RequiredBy),
+ {Callers, Unknown} =
+ dialyzer_coordinator:sccs_to_pids(RequiredBy, Coordinator),
send_done(Callers, SCC),
- continue_broadcast_done(Unknown, SCC).
+ continue_broadcast_done(Unknown, SCC, Coordinator).
send_done(Callers, SCC) ->
?debug("Sending ~p: ~p\n",[SCC, Callers]),
SendSTFun = fun(PID) -> PID ! {done, SCC} end,
lists:foreach(SendSTFun, Callers).
-continue_broadcast_done([], _SCC) -> ok;
-continue_broadcast_done(Rest, SCC) ->
+continue_broadcast_done([], _SCC, _Coordinator) -> ok;
+continue_broadcast_done(Rest, SCC, Coordinator) ->
%% This time limit should be greater than the time required
%% by the coordinator to spawn all processes.
timer:sleep(500),
- {Callers, Unknown} = dialyzer_coordinator:sccs_to_pids(Rest),
+ {Callers, Unknown} = dialyzer_coordinator:sccs_to_pids(Rest, Coordinator),
send_done(Callers, SCC),
- continue_broadcast_done(Unknown, SCC).
+ continue_broadcast_done(Unknown, SCC, Coordinator).
wait_for_success_typings(#state{depends_on = DependsOn} = State) ->
receive