From 30361077904295cbc7471c44d4b15ae86bfb2f05 Mon Sep 17 00:00:00 2001 From: Luca Favatella Date: Fri, 25 Sep 2015 00:02:51 +0100 Subject: Clarify usage of coordinator by analysis_callgraph * Comment in dialyzer_analysis_callgraph what the call to dialyzer_coordinator does; * Delegate activation request to each dialyzer_worker; * There is no reason for the dialyzer_coordinator to request activation on behalf of the workers: let each worker request its own activation as it leads to more consistent dialyzer_worker module (activation is request as soon as status running is hit - reguardless of mode) and it reduces lines of code. * Clarify types in coordinator and worker e.g. make opaque and make type more strict. --- lib/dialyzer/src/dialyzer_analysis_callgraph.erl | 40 +++++++++++++++--------- lib/dialyzer/src/dialyzer_coordinator.erl | 19 +++++------ lib/dialyzer/src/dialyzer_worker.erl | 6 ++-- 3 files changed, 36 insertions(+), 29 deletions(-) (limited to 'lib/dialyzer') diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index ab3e622356..59d2c2b3be 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -31,14 +31,17 @@ -export([start/3]). +%%% Export for dialyzer_coordinator... -export([compile_init_result/0, - add_to_result/4, - start_compilation/2, + add_to_result/4]). +%%% ... and export for dialyzer_worker. +-export([start_compilation/2, continue_compilation/2]). -export_type([compile_init_data/0, - one_file_result/0, - compile_result/0]). + one_file_mid_error/0, + one_file_result_ok/0, + compile_result/0]). -include("dialyzer.hrl"). @@ -254,6 +257,10 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, {T1, _} = statistics(wall_clock), Callgraph = dialyzer_callgraph:new(), CompileInit = make_compile_init(State, Callgraph), + %% Spawn a worker per file - where each worker calls + %% start_compilation on its file, asks next label to coordinator and + %% calls continue_compilation - and let coordinator aggregate + %% results using (compile_init_result and) add_to_result. {{Failed, Modules}, NextLabel} = ?timing(Timing, "compile", _C1, dialyzer_coordinator:parallel_job(compile, Files, @@ -285,16 +292,18 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, send_log(Parent, Msg2), {Callgraph, CServer2}. --type compile_init_data() :: #compile_init{}. --type error_reason() :: string(). --type compile_result() :: {[{file:filename(), error_reason()}], - [module()]}. %%opaque --type one_file_result() :: {error, error_reason()} | - {ok, [dialyzer_callgraph:callgraph_edge()], - [mfa_or_funlbl()], module()}. %%opaque --type compile_mid_data() :: {module(), cerl:cerl(), - dialyzer_callgraph:callgraph(), - dialyzer_codeserver:codeserver()}. +-opaque compile_init_data() :: #compile_init{}. +-type error_reason() :: string(). +-opaque compile_result() :: {[{file:filename(), error_reason()}], + [module()]}. +-type one_file_mid_error() :: {error, error_reason()}. +-opaque one_file_result_ok() :: {ok, [dialyzer_callgraph:callgraph_edge()], + [mfa_or_funlbl()], module()}. +-type one_file_result() :: one_file_mid_error() | + one_file_result_ok(). +-type compile_mid_data() :: {module(), cerl:cerl(), + dialyzer_callgraph:callgraph(), + dialyzer_codeserver:codeserver()}. -spec compile_init_result() -> compile_result(). @@ -435,7 +444,8 @@ store_core(Mod, Core, Callgraph, CServer) -> CoreSize = cerl_trees:size(CoreTree), {ok, CoreSize, {Mod, CoreTree, Callgraph, CServer}}. --spec continue_compilation(integer(), compile_mid_data()) -> one_file_result(). +-spec continue_compilation(integer(), compile_mid_data()) -> + one_file_result_ok(). continue_compilation(NextLabel, {Mod, CoreTree, Callgraph, CServer}) -> {LabeledTree, _NewNextLabel} = cerl_trees:label(CoreTree, NextLabel), diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl index 3290161ca1..87cbd25b30 100644 --- a/lib/dialyzer/src/dialyzer_coordinator.erl +++ b/lib/dialyzer/src/dialyzer_coordinator.erl @@ -2,7 +2,7 @@ %%----------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2012. All Rights Reserved. +%% Copyright Ericsson AB 2006-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -29,8 +29,8 @@ %%% Export for dialyzer main process -export([parallel_job/4]). -%%% Exports for all possible workers --export([wait_activation/0, job_done/3]). +%%% Export for all possible workers +-export([job_done/3]). %%% Exports for the typesig and dataflow analysis workers -export([sccs_to_pids/2, request_activation/1]). @@ -46,7 +46,7 @@ -type regulator() :: pid(). -type scc_to_pid() :: ets:tid() | 'unused'. --type coordinator() :: {collector(), regulator(), scc_to_pid()}. %%opaque +-opaque coordinator() :: {collector(), regulator(), scc_to_pid()}. -type timing() :: dialyzer_timing:timing_server(). -type scc() :: [mfa_or_funlbl()]. @@ -75,8 +75,9 @@ -type result() :: compile_result() | typesig_result() | dataflow_result() | warnings_result(). --type job_result() :: dialyzer_analysis_callgraph:one_file_result() | - typesig_result() | dataflow_result() | warnings_result(). +-type job_result() :: dialyzer_analysis_callgraph:one_file_mid_error() | + dialyzer_analysis_callgraph:one_file_result_ok() | + typesig_result() | dataflow_result() | warnings_result(). -record(state, {mode :: mode(), active = 0 :: integer(), @@ -119,7 +120,7 @@ spawn_jobs(Mode, Jobs, InitData, Timing) -> Pid = dialyzer_worker:launch(Mode, Job, InitData, Coordinator), case TypesigOrDataflow of true -> true = ets:insert(SCCtoPID, {Job, Pid}), ok; - false -> request_activation(Regulator, Pid) + false -> ok end, Count + 1 end, @@ -218,10 +219,6 @@ request_activation({_Collector, Regulator, _SCCtoPID}) -> Regulator ! {req, self()}, wait_activation(). -request_activation(Regulator, Pid) -> - Regulator ! {req, Pid}, - ok. - spawn_regulator() -> InitTickets = dialyzer_utils:parallelism(), spawn_link(fun() -> regulator_loop(InitTickets, queue:new()) end). diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl index bae12b21c3..b9ab27c11d 100644 --- a/lib/dialyzer/src/dialyzer_worker.erl +++ b/lib/dialyzer/src/dialyzer_worker.erl @@ -25,7 +25,7 @@ -export_type([worker/0]). --type worker() :: pid(). %%opaque +-opaque worker() :: pid(). -type mode() :: dialyzer_coordinator:mode(). -type coordinator() :: dialyzer_coordinator:coordinator(). @@ -87,7 +87,7 @@ loop(waiting, #state{mode = Mode} = State) when NewState = wait_for_success_typings(State), loop(updating, NewState); loop(running, #state{mode = 'compile'} = State) -> - dialyzer_coordinator:wait_activation(), + dialyzer_coordinator:request_activation(State#state.coordinator), ?debug("Compile: ~s\n",[State#state.job]), Result = case start_compilation(State) of @@ -99,7 +99,7 @@ loop(running, #state{mode = 'compile'} = State) -> end, report_to_coordinator(Result, State); loop(running, #state{mode = 'warnings'} = State) -> - dialyzer_coordinator:wait_activation(), + dialyzer_coordinator:request_activation(State#state.coordinator), ?debug("Warning: ~s\n",[State#state.job]), Result = collect_warnings(State), report_to_coordinator(Result, State); -- cgit v1.2.3