aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel
diff options
context:
space:
mode:
authorGravatar gareuselesinge <gareuselesinge@85f007b7-540e-0410-9357-904b9bb8a0f7>2013-08-30 16:02:20 +0000
committerGravatar gareuselesinge <gareuselesinge@85f007b7-540e-0410-9357-904b9bb8a0f7>2013-08-30 16:02:20 +0000
commit519b9d2f30409f3cfda9dc403a56b1c332bba91f (patch)
tree6fc54dca1b3b5cc4e36f0629e0e79f8c1d08014e /toplevel
parent5c71dab804325a7aba5b49cf2e45b4470ea1dff1 (diff)
Make the jopin-document button wait for slaves to terminate
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@16750 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'toplevel')
-rw-r--r--toplevel/stm.ml35
1 files changed, 29 insertions, 6 deletions
diff --git a/toplevel/stm.ml b/toplevel/stm.ml
index f68c4c3ff..bae2a58fe 100644
--- a/toplevel/stm.ml
+++ b/toplevel/stm.ml
@@ -488,6 +488,9 @@ module Slaves : sig
val build_proof :
exn_info:(Stateid.t * Stateid.t) -> start:Stateid.t -> stop:Stateid.t ->
Entries.proof_output list Future.computation
+
+ (* blocking function that waits for the task queue to be empty *)
+ val wait_all_done : unit -> unit
(* initialize the whole machinery (optional) *)
val init : unit -> unit
@@ -508,40 +511,56 @@ end = struct (* {{{ *)
val create : unit -> 'a t
val pop : 'a t -> 'a
val push : 'a t -> 'a -> unit
+ val wait_until_n_are_waiting_and_queue_empty : int -> 'a t -> unit
end = struct (* {{{ *)
- type 'a t = 'a Queue.t * Mutex.t * Condition.t
+ (* queue, lock, cond_q, n_waiting, cond_n_waiting *)
+ type 'a t = 'a Queue.t * Mutex.t * Condition.t * int ref * Condition.t
let create () =
- Queue.create (), Mutex.create (), Condition.create ()
+ Queue.create (), Mutex.create (), Condition.create (),
+ ref 0, Condition.create ()
- let pop (q,m,c) =
+ let pop (q,m,c,n,cn) =
Mutex.lock m;
- while Queue.is_empty q do Condition.wait c m done;
+ while Queue.is_empty q do
+ n := !n+1;
+ Condition.signal cn;
+ Condition.wait c m;
+ n := !n-1
+ done;
let x = Queue.pop q in
- if not (Queue.is_empty q) then Condition.signal c;
+ Condition.signal c;
+ Condition.signal cn;
Mutex.unlock m;
x
- let push (q,m,c) x =
+ let push (q,m,c,n,cn) x =
Mutex.lock m;
Queue.push x q;
Condition.signal c;
Mutex.unlock m
+ let wait_until_n_are_waiting_and_queue_empty j (q,m,c,n,cn) =
+ Mutex.lock m;
+ while not (Queue.is_empty q) || !n < j do Condition.wait cn m done;
+ Mutex.unlock m
+
end (* }}} *)
module SlavesPool : sig
val init : ((unit -> in_channel * out_channel * int) -> unit) -> unit
val is_empty : unit -> bool
+ val n_slaves : unit -> int
end = struct (* {{{ *)
let slave_manager = ref (None : Thread.t option)
let is_empty () = Option.is_empty !slave_manager
+ let n_slaves () = if !slave_manager = None then 0 else 1
let respawn () =
let c2s_r, c2s_w = Unix.pipe () in
@@ -653,6 +672,9 @@ end = struct (* {{{ *)
let queue : task TQueue.t = TQueue.create ()
+ let wait_all_done () =
+ TQueue.wait_until_n_are_waiting_and_queue_empty (SlavesPool.n_slaves ()) queue
+
let build_proof ~exn_info ~start ~stop =
if SlavesPool.is_empty () then
build_proof_here exn_info stop
@@ -1049,6 +1071,7 @@ let join_aborted_proofs () =
let join () =
finish ();
VCS.print ();
+ Slaves.wait_all_done ();
prerr_endline "Joining the environment";
Global.join_safe_environment ();
VCS.print ();