aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel')
-rw-r--r--toplevel/ide_slave.ml22
-rw-r--r--toplevel/stm.ml123
-rw-r--r--toplevel/stm.mli3
-rw-r--r--toplevel/vernac.ml4
-rw-r--r--toplevel/vi_checking.ml4
5 files changed, 98 insertions, 58 deletions
diff --git a/toplevel/ide_slave.ml b/toplevel/ide_slave.ml
index 1b97a69ba..8ea5de365 100644
--- a/toplevel/ide_slave.ml
+++ b/toplevel/ide_slave.ml
@@ -233,9 +233,6 @@ let hints () =
(** Other API calls *)
-let inloadpath dir =
- Loadpath.is_in_load_paths (CUnix.physical_path_of_string dir)
-
let status force =
(** We remove the initial part of the current [DirPath.t]
(usually Top in an interactive session, cf "coqtop -top"),
@@ -301,9 +298,23 @@ let handle_exn e =
let init =
let initialized = ref false in
- fun () ->
+ fun file ->
if !initialized then anomaly (str "Already initialized")
- else (initialized := true; Stm.get_current_state ())
+ else begin
+ initialized := true;
+ match file with
+ | None -> Stm.get_current_state ()
+ | Some file ->
+ let dir = Filename.dirname file in
+ let open Loadpath in let open CUnix in
+ let initial_id, _ =
+ if not (is_in_load_paths (physical_path_of_string dir)) then
+ Stm.add false ~ontop:(Stm.get_current_state ())
+ 0 (Printf.sprintf "Add LoadPath \"%s\". " dir)
+ else Stm.get_current_state (), `NewTip in
+ Stm.set_compilation_hints file;
+ initial_id
+ end
(* Retrocompatibility stuff *)
let interp ((_raw, verbose), s) =
@@ -344,7 +355,6 @@ let eval_call xml_oc log c =
Interface.hints = interruptible hints;
Interface.status = interruptible status;
Interface.search = interruptible search;
- Interface.inloadpath = interruptible inloadpath;
Interface.get_options = interruptible get_options;
Interface.set_options = interruptible set_options;
Interface.mkcases = interruptible Vernacentries.make_cases;
diff --git a/toplevel/stm.ml b/toplevel/stm.ml
index 9cb5e9511..c61258655 100644
--- a/toplevel/stm.ml
+++ b/toplevel/stm.ml
@@ -502,8 +502,8 @@ module State : sig
val install_cached : Stateid.t -> unit
val is_cached : Stateid.t -> bool
- val exn_on : Stateid.t -> ?valid:Stateid.t -> exn -> exn
+ val exn_on : Stateid.t -> ?valid:Stateid.t -> exn -> exn
(* to send states across worker/master *)
type frozen_state
val get_cached : Stateid.t -> frozen_state
@@ -595,13 +595,18 @@ end
(* }}} *)
let hints = ref Aux_file.empty_aux_file
-let set_compilation_hints h = hints := h
+let set_compilation_hints file =
+ hints := Aux_file.load_aux_file_for file
let get_hint_ctx loc =
let s = Aux_file.get !hints loc "context_used" in
let ids = List.map Names.Id.of_string (Str.split (Str.regexp " ") s) in
let ids = List.map (fun id -> Loc.ghost, id) ids in
SsExpr (SsSet ids)
+let get_hint_bp_time proof_name =
+ try float_of_string (Aux_file.get !hints Loc.ghost proof_name)
+ with Not_found -> 1.0
+
module Worker = Spawn.Sync(struct
let add_timeout ~sec f =
ignore(Thread.create (fun () ->
@@ -612,6 +617,14 @@ module Worker = Spawn.Sync(struct
())
end)
+let record_pb_time proof_name loc time =
+ let proof_build_time = Printf.sprintf "%.3f" time in
+ Aux_file.record_in_aux_at loc "proof_build_time" proof_build_time;
+ if proof_name <> "" then begin
+ Aux_file.record_in_aux_at Loc.ghost proof_name proof_build_time;
+ hints := Aux_file.set !hints Loc.ghost proof_name proof_build_time
+ end
+
(* Slave processes (if initialized, otherwise local lazy evaluation) *)
module Slaves : sig
@@ -773,7 +786,7 @@ end = struct (* {{{ *)
let name_of_request (ReqBuildProof (_,_,_,_,_,s)) = s
type response =
- | RespBuiltProof of Entries.proof_output list
+ | RespBuiltProof of Entries.proof_output list * float
| RespError of (* err, safe, msg, safe_state *)
Stateid.t * Stateid.t * std_ppcmds * State.frozen_state option
| RespFeedback of Interface.feedback
@@ -825,7 +838,8 @@ end = struct (* {{{ *)
| ReqBuildProof(exn_info,eop,vcs,loc,_,_) ->
VCS.restore vcs;
VCS.print ();
- let r = RespBuiltProof (
+ let rc, time =
+ let wall_clock = Unix.gettimeofday () in
let l = Future.force (build_proof_here exn_info loc eop) in
List.iter (fun (_,se) -> Declareops.iter_side_effects (function
| Declarations.SEsubproof(_,
@@ -833,9 +847,9 @@ end = struct (* {{{ *)
Opaqueproof.join_opaque f
| _ -> ())
se) l;
- l) in
+ l, Unix.gettimeofday () -. wall_clock in
VCS.print ();
- r
+ RespBuiltProof(rc,time)
let check_task_aux extra name l i =
match List.nth l i with
@@ -974,8 +988,8 @@ end = struct (* {{{ *)
try `Val (build_proof_here_core loc stop ()) with e -> `Exn e in
let f,assign = Future.create_delegate ~force (State.exn_on id ~valid) in
let uuid = Future.uuid f in
- TQueue.push queue
- (TaskBuildProof(exn_info,start,stop,assign,cancel_switch,loc,uuid,name));
+ TQueue.push queue (TaskBuildProof
+ (exn_info,start,stop,assign,cancel_switch,loc,uuid,name));
f, cancel_switch
end else
build_proof_here exn_info loc stop, cancel_switch
@@ -983,8 +997,8 @@ end = struct (* {{{ *)
let f, assign = Future.create_delegate (State.exn_on id ~valid) in
let uuid = Future.uuid f in
Pp.feedback (Interface.InProgress 1);
- TQueue.push queue
- (TaskBuildProof(exn_info,start,stop,assign,cancel_switch,loc,uuid,name));
+ TQueue.push queue (TaskBuildProof
+ (exn_info,start,stop,assign,cancel_switch,loc,uuid,name));
f, cancel_switch
exception RemoteException of std_ppcmds
@@ -1028,13 +1042,16 @@ end = struct (* {{{ *)
let rec loop () =
let response = unmarshal_response ic in
match task, response with
- | TaskBuildProof(_,_,_, assign,_,_,_,_), RespBuiltProof pl ->
+ | TaskBuildProof(_,_,_, assign,_,loc,_,s),
+ RespBuiltProof(pl, time)->
assign (`Val pl);
(* We restart the slave, to avoid memory leaks. We could just
Pp.feedback (Interface.InProgress ~-1) *)
+ record_pb_time s loc time;
last_task := None;
raise KillRespawn
- | TaskBuildProof(_,_,_, assign,_,_,_,_),RespError(err_id,valid,e,s) ->
+ | TaskBuildProof(_,_,_, assign,_,_,_,_),
+ RespError(err_id,valid,e,s) ->
let e = Stateid.add ~valid (RemoteException e) err_id in
assign (`Exn e);
Option.iter (State.assign valid) s;
@@ -1216,15 +1233,19 @@ end = struct (* {{{ *)
let pstate = ["meta counter"; "evar counter"; "program-tcc-table"]
-let delegate_policy_check () =
+let delegate_policy_check time =
if interactive () = `Yes then
- !Flags.async_proofs_mode = Flags.APonParallel 0 ||
- !Flags.async_proofs_mode = Flags.APonLazy
+ (!Flags.async_proofs_mode = Flags.APonParallel 0 ||
+ !Flags.async_proofs_mode = Flags.APonLazy) && time >= 1.0
else if !Flags.compilation_mode = Flags.BuildVi then true
else !Flags.async_proofs_mode <> Flags.APoff
let collect_proof cur hd brkind id =
prerr_endline ("Collecting proof ending at "^Stateid.to_string id);
+ let no_name = "" in
+ let name = function
+ | [] -> no_name
+ | id :: _ -> Id.to_string id in
let loc = (snd cur).loc in
let is_defined = function
| _, { expr = VernacEndProof (Proved (false,_)) } -> true
@@ -1233,40 +1254,54 @@ let collect_proof cur hd brkind id =
let view = VCS.visit id in
match last, view.step with
| _, `Cmd (x, _) -> collect (Some (id,x)) (id::accn) view.next
- | _, `Alias _ -> `Sync `Alias
- | _, `Fork(_,_,_,_::_::_)-> `Sync `MutualProofs
+ | _, `Alias _ -> `Sync (no_name,`Alias)
+ | _, `Fork(_,_,_,_::_::_)-> `Sync (no_name,`MutualProofs)
| _, `Fork(_,_,Doesn'tGuaranteeOpacity,_) ->
- `Sync `Doesn'tGuaranteeOpacity
+ `Sync (no_name,`Doesn'tGuaranteeOpacity)
| Some (parent, ({ expr = VernacProof(_,Some _)} as v)),
`Fork (_, hd', GuaranteesOpacity, ids) ->
+ let name = name ids in
+ let time = get_hint_bp_time name in
assert (VCS.Branch.equal hd hd' || VCS.Branch.equal hd VCS.edit_branch);
- if delegate_policy_check () then `ASync (parent,Some v,accn,ids)
- else `Sync `Policy
+ if delegate_policy_check time
+ then `ASync (parent,Some v,accn,name)
+ else `Sync (name,`Policy)
| Some (parent, ({ expr = VernacProof(t,None)} as v)),
`Fork (_, hd', GuaranteesOpacity, ids) when
not (State.is_cached parent) &&
!Flags.compilation_mode = Flags.BuildVi ->
(try
- let hint = get_hint_ctx loc in
+ let name = name ids in
+ let hint, time = get_hint_ctx loc, get_hint_bp_time name in
assert (VCS.Branch.equal hd hd'||VCS.Branch.equal hd VCS.edit_branch);
v.expr <- VernacProof(t, Some hint);
- if delegate_policy_check () then `ASync (parent,Some v,accn,ids)
- else `Sync `Policy
- with Not_found -> `Sync `NoHint)
+ if delegate_policy_check time
+ then `ASync (parent,Some v,accn,name)
+ else `Sync (name,`Policy)
+ with Not_found -> `Sync (no_name,`NoHint))
| Some (parent, _), `Fork (_, hd', GuaranteesOpacity, ids) ->
assert (VCS.Branch.equal hd hd' || VCS.Branch.equal hd VCS.edit_branch);
- if delegate_policy_check () then `MaybeASync (parent, accn, ids)
- else `Sync `Policy
- | _, `Sideff _ -> `Sync `NestedProof
- | _ -> `Sync `Unknown in
+ let name = name ids in
+ let time = get_hint_bp_time name in
+ if delegate_policy_check time
+ then `MaybeASync (parent, accn, name)
+ else `Sync (name,`Policy)
+ | _, `Sideff _ -> `Sync (no_name,`NestedProof)
+ | _ -> `Sync (no_name,`Unknown) in
match cur, (VCS.visit id).step, brkind with
|( parent, { expr = VernacExactProof _ }), `Fork _, _ ->
- `Sync `Immediate
+ `Sync (no_name,`Immediate)
| _, _, { VCS.kind = `Edit _ } -> collect (Some cur) [] id
| _ ->
- if State.is_cached id then `Sync `AlreadyEvaluated
- else if is_defined cur then `Sync `Transparent
- else collect (Some cur) [] id
+ if is_defined cur then `Sync (no_name,`Transparent)
+ else
+ let rc = collect (Some cur) [] id in
+ if not (State.is_cached id) then rc
+ else (* we already have the proof, no gain in delaying *)
+ match rc with
+ | `Sync(name,_) -> `Sync (name,`AlreadyEvaluated)
+ | `MaybeASync(_,_,name) -> `Sync (name,`AlreadyEvaluated)
+ | `ASync(_,_,_,name) -> `Sync (name,`AlreadyEvaluated)
let string_of_reason = function
| `Transparent -> "Transparent"
@@ -1318,7 +1353,7 @@ let known_state ?(redefine_qed=false) ~cache id =
), `Yes
| `Qed ({ qast = x; keep; brinfo; brname } as qed, eop) ->
let rec aux = function
- | `ASync (start, proof_using_ast, nodes,ids) -> (fun () ->
+ | `ASync (start, proof_using_ast, nodes, name) -> (fun () ->
prerr_endline ("Asynchronous " ^ Stateid.to_string id);
VCS.create_cluster nodes ~tip:id;
begin match keep, brinfo, qed.fproof with
@@ -1327,16 +1362,14 @@ let known_state ?(redefine_qed=false) ~cache id =
assert(redefine_qed = true);
VCS.create_cluster nodes ~tip:id;
let fp, cancel = Slaves.build_proof
- ~loc:x.loc ~exn_info:(id,eop) ~start ~stop:eop
- ~name:(String.concat " " (List.map Id.to_string ids)) in
+ ~loc:x.loc ~exn_info:(id,eop) ~start ~stop:eop ~name in
Future.replace ofp fp;
qed.fproof <- Some (fp, cancel)
| VtKeep, { VCS.kind = `Proof _ }, Some _ -> assert false
| VtKeep, { VCS.kind = `Proof _ }, None ->
reach ~cache:`Shallow start;
let fp, cancel = Slaves.build_proof
- ~loc:x.loc ~exn_info:(id,eop) ~start ~stop:eop
- ~name:(String.concat " " (List.map Id.to_string ids)) in
+ ~loc:x.loc ~exn_info:(id,eop) ~start ~stop:eop ~name in
qed.fproof <- Some (fp, cancel);
let proof =
Proof_global.close_future_proof ~feedback_id:id fp in
@@ -1351,17 +1384,16 @@ let known_state ?(redefine_qed=false) ~cache id =
end;
Proof_global.discard_all ()
), if redefine_qed then `No else `Yes
- | `Sync `Immediate -> (fun () ->
+ | `Sync (name, `Immediate) -> (fun () ->
assert (Stateid.equal view.next eop);
reach eop; vernac_interp id x; Proof_global.discard_all ()
), `Yes
- | `Sync reason -> (fun () ->
+ | `Sync (name, reason) -> (fun () ->
prerr_endline ("Synchronous " ^ Stateid.to_string id ^ " " ^
string_of_reason reason);
reach eop;
let wall_clock = Unix.gettimeofday () in
- Aux_file.record_in_aux_at x.loc "proof_build_time"
- (Printf.sprintf "%.3f" (wall_clock -. !wall_clock_last_fork));
+ record_pb_time name x.loc (wall_clock -. !wall_clock_last_fork);
begin match keep with
| VtKeep ->
let proof =
@@ -1378,16 +1410,13 @@ let known_state ?(redefine_qed=false) ~cache id =
end;
Proof_global.discard_all ()
), `Yes
- | `MaybeASync (start, nodes, ids) -> (fun () ->
+ | `MaybeASync (start, nodes, name) -> (fun () ->
prerr_endline ("MaybeAsynchronous " ^ Stateid.to_string id);
reach ~cache:`Shallow start;
(* no sections *)
if List.is_empty (Environ.named_context (Global.env ()))
- (* && Safe_typing.is_curmod_library (Global.safe_env ()) *)
- then
- fst (aux (`ASync (start, None, nodes,ids))) ()
- else
- fst (aux (`Sync `Unknown)) ()
+ then fst (aux (`ASync (start, None, nodes, name))) ()
+ else fst (aux (`Sync (name, `Unknown))) ()
), if redefine_qed then `No else `Yes
in
aux (collect_proof (view.next, x) brname brinfo eop)
diff --git a/toplevel/stm.mli b/toplevel/stm.mli
index 1eba274ab..cd9245895 100644
--- a/toplevel/stm.mli
+++ b/toplevel/stm.mli
@@ -60,7 +60,8 @@ val init : unit -> unit
val slave_main_loop : unit -> unit
val slave_init_stdout : unit -> unit
-val set_compilation_hints : Aux_file.aux_file -> unit
+(* Filename *)
+val set_compilation_hints : string -> unit
(** read-eval-print loop compatible interface ****************************** **)
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index 11cb726c7..27509fcc0 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -336,7 +336,7 @@ let compile verbosely f =
| BuildVi ->
let ldir, long_f_dot_v = Flags.verbosely Library.start_library f in
Dumpglob.noglob ();
- Stm.set_compilation_hints (Aux_file.load_aux_file_for long_f_dot_v);
+ Stm.set_compilation_hints long_f_dot_v;
let _ = load_vernac verbosely long_f_dot_v in
Stm.finish ();
check_pending_proofs ();
@@ -347,7 +347,7 @@ let compile verbosely f =
Dumpglob.noglob ();
let f = if check_suffix f ".vi" then chop_extension f else f in
let lfdv, lib, univs, disch, tasks, proofs = load_library_todo f in
- Stm.set_compilation_hints (Aux_file.load_aux_file_for lfdv);
+ Stm.set_compilation_hints lfdv;
let univs, proofs = Stm.finish_tasks lfdv univs disch proofs tasks in
Library.save_library_raw lfdv lib univs proofs
diff --git a/toplevel/vi_checking.ml b/toplevel/vi_checking.ml
index 37f4266d0..cb6e60136 100644
--- a/toplevel/vi_checking.ml
+++ b/toplevel/vi_checking.ml
@@ -11,7 +11,7 @@ open Util
let check_vi (ts,f) =
Dumpglob.noglob ();
let long_f_dot_v, _, _, _, tasks, _ = Library.load_library_todo f in
- Stm.set_compilation_hints (Aux_file.load_aux_file_for long_f_dot_v);
+ Stm.set_compilation_hints long_f_dot_v;
List.fold_left (fun acc ids -> Stm.check_task f tasks ids && acc) true ts
module Worker = Spawn.Sync(struct
@@ -39,7 +39,7 @@ let schedule_vi_checking j fs =
if Filename.check_suffix f ".vi" then Filename.chop_extension f
else f in
let long_f_dot_v, _,_,_, tasks, _ = Library.load_library_todo f in
- Stm.set_compilation_hints (Aux_file.load_aux_file_for long_f_dot_v);
+ Stm.set_compilation_hints long_f_dot_v;
let infos = Stm.info_tasks tasks in
let eta = List.fold_left (fun a (_,t,_) -> a +. t) 0.0 infos in
if infos <> [] then jobs := (f, eta, infos) :: !jobs)