src/Pure/Thy/thy_info.ML
changeset 44162 5434899d955c
parent 44113 0baa8bbd355a
child 44186 806f0ec1a43d
equal deleted inserted replaced
44161:c1da9897b6c9 44162:5434899d955c
   176   Finished of theory;
   176   Finished of theory;
   177 
   177 
   178 fun task_finished (Task _) = false
   178 fun task_finished (Task _) = false
   179   | task_finished (Finished _) = true;
   179   | task_finished (Finished _) = true;
   180 
   180 
       
   181 fun task_parents deps (parents: string list) = map (the o AList.lookup (op =) deps) parents;
       
   182 
   181 local
   183 local
   182 
   184 
   183 fun finish_thy ((thy, present, commit): result) =
   185 fun finish_thy ((thy, present, commit): result) =
   184   (Global_Theory.join_proofs thy; Future.join present; commit (); thy);
   186   (Global_Theory.join_proofs thy; Future.join present; commit (); thy);
   185 
   187 
   186 fun schedule_seq task_graph =
   188 val schedule_seq =
   187   ((Graph.topological_order task_graph, Symtab.empty) |-> fold (fn name => fn tab =>
   189   Graph.schedule (fn deps => fn (_, task) =>
   188     (case Graph.get_node task_graph name of
   190     (case task of
       
   191       Task (parents, body) => finish_thy (body (task_parents deps parents))
       
   192     | Finished thy => thy)) #> ignore;
       
   193 
       
   194 val schedule_futures = uninterruptible (fn _ =>
       
   195   Graph.schedule (fn deps => fn (name, task) =>
       
   196     (case task of
   189       Task (parents, body) =>
   197       Task (parents, body) =>
   190         let val result = body (map (the o Symtab.lookup tab) parents)
   198         singleton
   191         in Symtab.update (name, finish_thy result) tab end
   199           (Future.forks
   192     | Finished thy => Symtab.update (name, thy) tab))) |> ignore;
   200             {name = "theory:" ^ name, group = NONE,
   193 
   201               deps = map (Future.task_of o #2) deps,
   194 fun schedule_futures task_graph = uninterruptible (fn _ => fn () =>
   202               pri = 0, interrupts = true})
   195   let
   203           (fn () =>
   196     val tasks = Graph.topological_order task_graph;
   204             (case filter (not o can Future.join o #2) deps of
   197     val futures = (tasks, Symtab.empty) |-> fold (fn name => fn tab =>
   205               [] => body (map (#1 o Future.join) (task_parents deps parents))
   198       (case Graph.get_node task_graph name of
   206             | bad =>
   199         Task (parents, body) =>
   207                 error (loader_msg ("failed to load " ^ quote name ^
   200           let
   208                   " (unresolved " ^ commas_quote (map #1 bad) ^ ")") [])))
   201             val get = the o Symtab.lookup tab;
   209     | Finished thy => Future.value (thy, Future.value (), I)))
   202             val deps = map (`get) (Graph.imm_preds task_graph name);
   210   #> maps (fn result => (finish_thy (Future.join result); []) handle exn => [Exn.Exn exn])
   203             val task_deps = map (Future.task_of o #1) deps;
   211   #> rev #> Exn.release_all) #> ignore;
   204             fun failed (future, parent) = if can Future.join future then NONE else SOME parent;
       
   205 
       
   206             val future =
       
   207               singleton
       
   208                 (Future.forks
       
   209                   {name = "theory:" ^ name, group = NONE, deps = task_deps, pri = 0,
       
   210                     interrupts = true})
       
   211                 (fn () =>
       
   212                   (case map_filter failed deps of
       
   213                     [] => body (map (#1 o Future.join o get) parents)
       
   214                   | bad => error (loader_msg ("failed to load " ^ quote name ^
       
   215                       " (unresolved " ^ commas_quote bad ^ ")") [])));
       
   216           in Symtab.update (name, future) tab end
       
   217       | Finished thy => Symtab.update (name, Future.value (thy, Future.value (), I)) tab));
       
   218     val _ =
       
   219       tasks |> maps (fn name =>
       
   220         let
       
   221           val result = Future.join (the (Symtab.lookup futures name));
       
   222           val _ = finish_thy result;
       
   223         in [] end handle exn => [Exn.Exn exn])
       
   224       |> rev |> Exn.release_all;
       
   225   in () end) ();
       
   226 
   212 
   227 in
   213 in
   228 
   214 
   229 fun schedule_tasks tasks =
   215 fun schedule_tasks tasks =
   230   if not (Multithreading.enabled ()) then schedule_seq tasks
   216   if not (Multithreading.enabled ()) then schedule_seq tasks