diff options
Diffstat (limited to 'lib/dialyzer/src/dialyzer_worker.erl')
-rw-r--r-- | lib/dialyzer/src/dialyzer_worker.erl | 119 |
1 files changed, 41 insertions, 78 deletions
diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl index af0f2e9e08..c9ceb75a40 100644 --- a/lib/dialyzer/src/dialyzer_worker.erl +++ b/lib/dialyzer/src/dialyzer_worker.erl @@ -12,6 +12,8 @@ %% See the License for the specific language governing permissions and %% limitations under the License. +%% Purpose: Run individual jobs in separate processes. + -module(dialyzer_worker). -export([launch/4]). @@ -29,12 +31,9 @@ mode :: mode(), job :: job(), coordinator :: coordinator(), - init_data :: init_data(), - depends_on = [] :: list() + init_data :: init_data() }). --include("dialyzer.hrl"). - %% -define(DEBUG, true). -ifdef(DEBUG). @@ -55,85 +54,46 @@ launch(Mode, Job, InitData, Coordinator) -> spawn_link(fun() -> init(State) end). %%-------------------------------------------------------------------- +%% Local functions. -init(#state{job = SCC, mode = Mode, init_data = InitData, - coordinator = Coordinator} = State) when - Mode =:= 'typesig'; Mode =:= 'dataflow' -> - DependsOnSCCs = dialyzer_succ_typings:find_depends_on(SCC, InitData), - ?debug("~w: Deps ~p: ~p\n", [self(), SCC, DependsOnSCCs]), - Pids = dialyzer_coordinator:sccs_to_pids(DependsOnSCCs, Coordinator), - ?debug("~w: PidsDeps ~p\n", [self(), Pids]), - DependsOn = [{Pid, erlang:monitor(process, Pid)} || Pid <- Pids], - loop(updating, State#state{depends_on = DependsOn}); +init(#state{job = SCC, mode = Mode, init_data = InitData} = State) + when Mode =:= 'typesig'; Mode =:= 'dataflow' -> + wait_for_success_typings(SCC, InitData, State), + run(State); init(#state{mode = Mode} = State) when - Mode =:= 'compile'; Mode =:= 'warnings' -> - loop(running, State). - -loop(updating, #state{mode = Mode} = State) when - Mode =:= 'typesig'; Mode =:= 'dataflow' -> - ?debug("~w: Update: ~p\n", [self(), State#state.job]), - NextStatus = - case waits_more_success_typings(State) of - true -> waiting; - false -> running - end, - loop(NextStatus, State); -loop(waiting, #state{mode = Mode} = State) when - Mode =:= 'typesig'; Mode =:= 'dataflow' -> - ?debug("~w: Wait: ~p\n", [self(), State#state.job]), - NewState = wait_for_success_typings(State), - loop(updating, NewState); -loop(running, #state{mode = 'compile'} = State) -> - request_activation(State), - ?debug("Compile: ~s\n",[State#state.job]), - Result = - case start_compilation(State) of - {ok, EstimatedSize, Data} -> - Label = ask_coordinator_for_label(EstimatedSize, State), - continue_compilation(Label, Data); - {error, _Reason} = Error -> - Error - end, - report_to_coordinator(Result, State); -loop(running, #state{mode = 'warnings'} = State) -> - request_activation(State), - ?debug("Warning: ~s\n",[State#state.job]), - Result = collect_warnings(State), - report_to_coordinator(Result, State); -loop(running, #state{mode = Mode} = State) when - Mode =:= 'typesig'; Mode =:= 'dataflow' -> - request_activation(State), - ?debug("~w: Run: ~p\n", [self(), State#state.job]), - NotFixpoint = do_work(State), - report_to_coordinator(NotFixpoint, State). - -waits_more_success_typings(#state{depends_on = Depends}) -> - Depends =/= []. - -wait_for_success_typings(#state{depends_on = DependsOn} = State) -> - receive - {'DOWN', Ref, process, Pid, _Info} -> - ?debug("~w: ~p got DOWN: ~p\n", [self(), State#state.job, Pid]), - State#state{depends_on = DependsOn -- [{Pid, Ref}]} - after - 5000 -> - ?debug("~w: Still Waiting ~p:\n ~p\n", [self(), State#state.job, DependsOn]), - State - end. + Mode =:= 'compile'; Mode =:= 'warnings'; + Mode =:= 'contract_remote_types'; Mode =:= 'record_remote_types' -> + run(State). -request_activation(#state{coordinator = Coordinator}) -> - dialyzer_coordinator:request_activation(Coordinator). +run(#state{coordinator = Coordinator, job = Job} = State) -> + dialyzer_coordinator:request_activation(Coordinator), + Result = run_job(State), + ?debug("~w: Done: ~p\n",[self(), Job]), + dialyzer_coordinator:job_done(Job, Result, Coordinator). -do_work(#state{mode = Mode, job = Job, init_data = InitData}) -> +run_job(#state{mode = Mode, job = Job, init_data = InitData} = State) -> + ?debug("~w: ~p: ~p\n", [self(), Mode, Job]), case Mode of - typesig -> dialyzer_succ_typings:find_succ_types_for_scc(Job, InitData); - dataflow -> dialyzer_succ_typings:refine_one_module(Job, InitData) + compile -> + case start_compilation(State) of + {ok, EstimatedSize, Data} -> + Label = ask_coordinator_for_label(EstimatedSize, State), + continue_compilation(Label, Data); + {error, _Reason} = Error -> + Error + end; + typesig -> + dialyzer_succ_typings:find_succ_types_for_scc(Job, InitData); + dataflow -> + dialyzer_succ_typings:refine_one_module(Job, InitData); + contract_remote_types -> + dialyzer_contracts:process_contract_remote_types_module(Job, InitData); + record_remote_types -> + dialyzer_utils:process_record_remote_types_module(Job, InitData); + warnings -> + dialyzer_succ_typings:collect_warnings(Job, InitData) end. -report_to_coordinator(Result, #state{job = Job, coordinator = Coordinator}) -> - ?debug("~w: Done: ~p\n",[self(), Job]), - dialyzer_coordinator:job_done(Job, Result, Coordinator). - start_compilation(#state{job = Job, init_data = InitData}) -> dialyzer_analysis_callgraph:start_compilation(Job, InitData). @@ -143,5 +103,8 @@ ask_coordinator_for_label(EstimatedSize, #state{coordinator = Coordinator}) -> continue_compilation(Label, Data) -> dialyzer_analysis_callgraph:continue_compilation(Label, Data). -collect_warnings(#state{job = Job, init_data = InitData}) -> - dialyzer_succ_typings:collect_warnings(Job, InitData). +%% Wait for the results of success typings of modules or SCCs that we +%% depend on. ('typesig' or 'dataflow' mode) +wait_for_success_typings(SCC, InitData, #state{coordinator = Coordinator}) -> + DependsOnSCCs = dialyzer_succ_typings:find_depends_on(SCC, InitData), + dialyzer_coordinator:wait_for_success_typings(DependsOnSCCs, Coordinator). |