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
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
|