* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
-(** This module manages parallel jobs.
+(** This module manages parallel jobs. *)
- Jobs are grouped. You call [new_group] to create a new
- group of jobs, initially empty. Then add jobs to it. Then
- wait for all the jobs in the group to complete.
+type 'a next = Job of 'a * (unit -> unit) | Complete | Not_ready
- To submit a job to a group use [start group key f]. [group]
- is an existing group of jobs to which this is added. [key] is
- a key which ensures that two identical jobs cannot be running
- at the same time (across all groups). If two or more jobs
- with the same key are submitted then only one will run and
- the others will wait until the first finishes, and then another
- will be picked to run and so on. Jobs with different keys run
- freely in parallel, assuming there are enough threads available
- to run them.
+val run : (unit -> 'a next) -> ('a -> unit) -> ('a -> unit) ->
+ ('a -> string) -> unit
+(** [run next_job retire_job fail_job to_string] runs jobs in parallel.
- Goals uses the goal (name + parameters) as the key to
- ensure you cannot have two jobs running at the same time
- which would interfere with each other by trying to build
- the same target.
+ [next_job] is called to pick the next available job.
+ [retire_job] is called when a job finishes successfully.
+ [fail_job] is called when a job fails (only in keep-going
+ -k mode). All jobs that depend on this one must be marked
+ failed by the caller.
+ [to_string] is called if we need to print the job name.
- To wait for a group of jobs to complete, call [wait group].
- *)
-
-module type Key = sig
- type t
- val compare : t -> t -> int
- val to_string : t -> string
-end
-
-module type Jobs = sig
- type key
- type group
-
- val new_group : unit -> group
- (** Create a new empty jobs group. *)
-
- val start : group -> key -> (unit -> unit) -> unit
- (** [start group key f] submits a job to run in the background.
- The [key] ensures that two jobs with the same key cannot run
- at the same time (across all groups). *)
+ If [next_job] returns [Job f] then that function is started
+ (usually in a thread if -j N > 1).
- val wait : group -> unit
- (** [wait group] waits for all of the jobs in the group to finish. *)
+ If [next_job] returns [Complete] then [run] waits until
+ all parallel jobs are finished then returns.
- val stop_all : unit -> unit
- (** This is used when goals exits with an error. All jobs which
- are waiting to run are deleted, and we wait for all running
- jobs to finish. *)
-end
+ If [next_job] returns [Not_ready] then [next_job] will be
+ called again after a little while.
-module Make (K : Key) : Jobs with type key = K.t
+ If any job throws an exception then the exception will be
+ reraised by [run], usually causing goals to exit with an error.
+ The exception is delayed until all currently running jobs
+ finish. In normal mode no new jobs will be started during
+ this time. In keep-going -k mode new jobs may be started. *)