You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
2.2 KiB

(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module L = Logging
let of_list (lst : 'a list) : 'a ProcessPool.TaskGenerator.t =
let content = Queue.of_list lst in
let remaining = ref (Queue.length content) in
let remaining_tasks () = !remaining in
let is_empty () = Int.equal !remaining 0 in
let finished ~completed work = if completed then decr remaining else Queue.enqueue content work in
let next () = Queue.dequeue content in
{remaining_tasks; is_empty; finished; next}
let make sources =
let pnames =
List.map sources ~f:SourceFiles.proc_names_of_source
|> List.concat
|> List.rev_map ~f:(fun procname -> SchedulerTypes.Procname procname)
in
let files = List.map sources ~f:(fun file -> SchedulerTypes.File file) in
let permute = List.permute ~random_state:(Random.State.make (Array.create ~len:1 0)) in
permute pnames @ permute files |> of_list
let if_restart_scheduler f =
if Int.equal Config.jobs 1 then ()
else match Config.scheduler with File | SyntacticCallGraph -> () | Restart -> f ()
let locked_procs = Stack.create ()
let record_locked_proc (pname : Procname.t) = Stack.push locked_procs pname
let unlock_all () = Stack.until_empty locked_procs ProcLocker.unlock
let lock_exn pname =
if_restart_scheduler (fun () ->
if ProcLocker.try_lock pname then record_locked_proc pname
else (
unlock_all () ;
raise ProcessPool.ProcnameAlreadyLocked ) )
let unlock pname =
if_restart_scheduler (fun () ->
match Stack.pop locked_procs with
| None ->
L.die InternalError "Trying to unlock %s but it does not appear to be locked.@."
(Procname.to_string pname)
| Some stack_pname when not (Procname.equal pname stack_pname) ->
L.die InternalError "Trying to unlock %s but top of stack is %s.@."
(Procname.to_string pname) (Procname.to_string stack_pname)
| Some _ ->
ProcLocker.unlock pname )
let setup () = if_restart_scheduler ProcLocker.setup
let clean () = if_restart_scheduler ProcLocker.clean