diff --git a/infer/src/absint/AbstractInterpreter.ml b/infer/src/absint/AbstractInterpreter.ml index 8b733d1bd..3922a3a29 100644 --- a/infer/src/absint/AbstractInterpreter.ml +++ b/infer/src/absint/AbstractInterpreter.ml @@ -304,9 +304,16 @@ module AbstractInterpreterCommon (TransferFunctions : NodeTransferFunctions) = s | Ok post -> post | Error (exn, backtrace, instr) -> - if not !logged_error then ( - L.internal_error "In instruction %a@\n" (Sil.pp_instr ~print_types:true Pp.text) instr ; - logged_error := true ) ; + ( match exn with + | TaskSchedulerTypes.ProcnameAlreadyLocked _ -> + (* this isn't an error; don't log it *) + () + | _ -> + if not !logged_error then ( + L.internal_error "In instruction %a@\n" + (Sil.pp_instr ~print_types:true Pp.text) + instr ; + logged_error := true ) ) ; Caml.Printexc.raise_with_backtrace exn backtrace in (* hack to ensure that we call `exec_instr` on a node even if it has no instructions *) diff --git a/infer/src/backend/SchedulerTypes.ml b/infer/src/absint/TaskSchedulerTypes.ml similarity index 59% rename from infer/src/backend/SchedulerTypes.ml rename to infer/src/absint/TaskSchedulerTypes.ml index 679ec3bb4..4550df667 100644 --- a/infer/src/backend/SchedulerTypes.ml +++ b/infer/src/absint/TaskSchedulerTypes.ml @@ -6,4 +6,8 @@ *) open! IStd +exception ProcnameAlreadyLocked of Procname.t +(** for the Restart scheduler: raise when a worker tries to analyze a procedure already being + analyzed by another process *) + type target = Procname of Procname.t | File of SourceFile.t diff --git a/infer/src/backend/FileScheduler.ml b/infer/src/backend/FileScheduler.ml index 705902159..ec6a0bc70 100644 --- a/infer/src/backend/FileScheduler.ml +++ b/infer/src/backend/FileScheduler.ml @@ -7,7 +7,7 @@ open! IStd let make sources = - let open SchedulerTypes in + let open TaskSchedulerTypes in let gen = List.rev_map sources ~f:(fun sf -> File sf) |> List.permute ~random_state:(Random.State.make (Array.create ~len:1 0)) diff --git a/infer/src/backend/FileScheduler.mli b/infer/src/backend/FileScheduler.mli index 32ba8fc52..945815b23 100644 --- a/infer/src/backend/FileScheduler.mli +++ b/infer/src/backend/FileScheduler.mli @@ -6,4 +6,4 @@ *) open! IStd -val make : SourceFile.t list -> (SchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t +val make : SourceFile.t list -> (TaskSchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t diff --git a/infer/src/backend/InferAnalyze.ml b/infer/src/backend/InferAnalyze.ml index eed1961fe..c1c17c04e 100644 --- a/infer/src/backend/InferAnalyze.ml +++ b/infer/src/backend/InferAnalyze.ml @@ -19,7 +19,7 @@ let clear_caches_except_lrus () = let clear_caches () = Ondemand.LocalCache.clear () ; clear_caches_except_lrus () -let analyze_target : (SchedulerTypes.target, Procname.t) Tasks.doer = +let analyze_target : (TaskSchedulerTypes.target, Procname.t) Tasks.doer = let analyze_source_file exe_env source_file = if Topl.is_active () then DB.Results_dir.init (Topl.sourcefile ()) ; DB.Results_dir.init source_file ; @@ -30,7 +30,7 @@ let analyze_target : (SchedulerTypes.target, Procname.t) Tasks.doer = DotCfg.emit_frontend_cfg (Topl.sourcefile ()) (Topl.cfg ()) ; if Config.write_html then Printer.write_all_html_files source_file ; None - with RestartScheduler.ProcnameAlreadyLocked pname -> Some pname ) + with TaskSchedulerTypes.ProcnameAlreadyLocked pname -> Some pname ) in (* In call-graph scheduling, log progress every [per_procedure_logging_granularity] procedures. The default roughly reflects the average number of procedures in a C++ file. *) @@ -46,7 +46,7 @@ let analyze_target : (SchedulerTypes.target, Procname.t) Tasks.doer = try Ondemand.analyze_proc_name_toplevel exe_env proc_name ; None - with RestartScheduler.ProcnameAlreadyLocked pname -> Some pname + with TaskSchedulerTypes.ProcnameAlreadyLocked pname -> Some pname in fun target -> let exe_env = Exe_env.mk () in @@ -124,7 +124,9 @@ let tasks_generator_builder_for sources = let analyze source_files_to_analyze = if Int.equal Config.jobs 1 then ( - let target_files = List.rev_map source_files_to_analyze ~f:(fun sf -> SchedulerTypes.File sf) in + let target_files = + List.rev_map source_files_to_analyze ~f:(fun sf -> TaskSchedulerTypes.File sf) + in Tasks.run_sequentially ~f:analyze_target target_files ; BackendStats.get () ) else ( diff --git a/infer/src/backend/RestartScheduler.ml b/infer/src/backend/RestartScheduler.ml index 1de82be57..b745b96f6 100644 --- a/infer/src/backend/RestartScheduler.ml +++ b/infer/src/backend/RestartScheduler.ml @@ -7,9 +7,7 @@ open! IStd module L = Logging -exception ProcnameAlreadyLocked of Procname.t - -type work_with_dependency = {work: SchedulerTypes.target; need_to_finish: Procname.t option} +type work_with_dependency = {work: TaskSchedulerTypes.target; need_to_finish: Procname.t option} let of_list (lst : work_with_dependency list) : ('a, Procname.t) ProcessPool.TaskGenerator.t = let content = Queue.of_list lst in @@ -39,10 +37,10 @@ let make sources = List.map sources ~f:SourceFiles.proc_names_of_source |> List.concat |> List.rev_map ~f:(fun procname -> - {work= SchedulerTypes.Procname procname; need_to_finish= None} ) + {work= TaskSchedulerTypes.Procname procname; need_to_finish= None} ) in let files = - List.map sources ~f:(fun file -> {work= SchedulerTypes.File file; need_to_finish= None}) + List.map sources ~f:(fun file -> {work= TaskSchedulerTypes.File file; need_to_finish= None}) in let permute = List.permute ~random_state:(Random.State.make (Array.create ~len:1 0)) in permute pnames @ permute files |> of_list @@ -91,7 +89,7 @@ let lock_exn pname = if ProcLocker.try_lock pname then record_locked_proc pname else ( unlock_all () ; - raise (ProcnameAlreadyLocked pname) ) ) + raise (TaskSchedulerTypes.ProcnameAlreadyLocked pname) ) ) let unlock pname = diff --git a/infer/src/backend/RestartScheduler.mli b/infer/src/backend/RestartScheduler.mli index 9054c85be..79f08e1d3 100644 --- a/infer/src/backend/RestartScheduler.mli +++ b/infer/src/backend/RestartScheduler.mli @@ -6,8 +6,6 @@ *) open! IStd -exception ProcnameAlreadyLocked of Procname.t - val setup : unit -> unit val clean : unit -> unit @@ -16,4 +14,4 @@ val lock_exn : Procname.t -> unit val unlock : Procname.t -> unit -val make : SourceFile.t list -> (SchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t +val make : SourceFile.t list -> (TaskSchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t diff --git a/infer/src/backend/SyntacticCallGraph.ml b/infer/src/backend/SyntacticCallGraph.ml index a400b65f7..d9d75861c 100644 --- a/infer/src/backend/SyntacticCallGraph.ml +++ b/infer/src/backend/SyntacticCallGraph.ml @@ -96,8 +96,8 @@ let build_from_sources sources = g -let bottom_up sources : (SchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t = - let open SchedulerTypes in +let bottom_up sources : (TaskSchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t = + let open TaskSchedulerTypes in let syntactic_call_graph = build_from_sources sources in let remaining = ref (CallGraph.n_procs syntactic_call_graph) in let remaining_tasks () = !remaining in diff --git a/infer/src/backend/SyntacticCallGraph.mli b/infer/src/backend/SyntacticCallGraph.mli index 1c6dff799..8cc758d43 100644 --- a/infer/src/backend/SyntacticCallGraph.mli +++ b/infer/src/backend/SyntacticCallGraph.mli @@ -6,7 +6,7 @@ *) open! IStd -val make : SourceFile.t list -> (SchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t +val make : SourceFile.t list -> (TaskSchedulerTypes.target, Procname.t) ProcessPool.TaskGenerator.t (** task generator that works by - loading the syntactic call graph from the capture DB diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index 9d11d2b1a..6c7858a24 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -223,7 +223,7 @@ let run_proc_analysis ~caller_pdesc callee_pdesc = let backtrace = Printexc.get_backtrace () in IExn.reraise_if exn ~f:(fun () -> match exn with - | RestartScheduler.ProcnameAlreadyLocked _ -> + | TaskSchedulerTypes.ProcnameAlreadyLocked _ -> clear_actives () ; restore_global_state old_state ; true | _ -> if not !logged_error then (