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 |