371 val name = Path.implode (Path.base path); |
370 val name = Path.implode (Path.base path); |
372 val dir' = Path.append dir (Path.dir path); |
371 val dir' = Path.append dir (Path.dir path); |
373 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |
372 val _ = member (op =) initiators name andalso error (cycle_msg initiators); |
374 in |
373 in |
375 (case try (Graph.get_node (fst tasks)) name of |
374 (case try (Graph.get_node (fst tasks)) name of |
376 SOME task => (is_none task, tasks) |
375 SOME task => (Task.is_finished task, tasks) |
377 | NONE => |
376 | NONE => |
378 let |
377 let |
379 val (current, deps, parents) = check_deps ml strict dir' name |
378 val (current, deps, parents) = check_deps ml strict dir' name |
380 handle ERROR msg => cat_error msg |
379 handle ERROR msg => cat_error msg |
381 (loader_msg "the error(s) above occurred while examining theory" [name] ^ |
380 (loader_msg "the error(s) above occurred while examining theory" [name] ^ |
389 val all_current = current andalso parents_current; |
388 val all_current = current andalso parents_current; |
390 val thy = if all_current orelse not really then SOME (get_theory name) else NONE; |
389 val thy = if all_current orelse not really then SOME (get_theory name) else NONE; |
391 val _ = change_thys (new_deps name parent_names (deps, thy)); |
390 val _ = change_thys (new_deps name parent_names (deps, thy)); |
392 |
391 |
393 val tasks_graph'' = tasks_graph' |> new_deps name parent_names |
392 val tasks_graph'' = tasks_graph' |> new_deps name parent_names |
394 (if all_current then NONE |
393 (if all_current then Task.Finished |
395 else SOME (fn () => load_thy really ml time initiators dir' name)); |
394 else Task.Task (fn () => load_thy really ml time initiators dir' name)); |
396 val tasks_len'' = if all_current then tasks_len' else tasks_len' + 1; |
395 val tasks_len'' = if all_current then tasks_len' else tasks_len' + 1; |
397 in (all_current, (tasks_graph'', tasks_len'')) end) |
396 in (all_current, (tasks_graph'', tasks_len'')) end) |
398 end; |
397 end; |
399 |
398 |
400 end; |
399 end; |
401 |
400 |
402 |
401 |
403 (* use_thy etc. -- scheduling required theories *) |
402 (* variations on use_thy -- scheduling required theories *) |
404 |
403 |
405 local |
404 local |
406 |
405 |
407 fun schedule_seq tasks = |
406 fun schedule_seq tasks = |
408 Graph.topological_order tasks |
407 Graph.topological_order tasks |
409 |> List.app (fn name => the_default I (Graph.get_node tasks name) ()); |
408 |> List.app (fn name => (case Graph.get_node tasks name of Task.Task f => f () | _ => ())); |
410 |
409 |
411 fun next_task (SOME f :: fs, G) = (SOME f, (fs, G)) |
410 fun next_task G = |
412 | next_task (NONE :: fs, G) = next_task (fs, G) |
411 let |
413 | next_task ([], G) = |
412 val tasks = map (fn name => (name, Graph.get_node G name)) (Graph.minimals G); |
414 (case Graph.minimals G of |
413 val finished = filter (Task.is_finished o snd) tasks; |
415 [] => (NONE, ([], G)) |
414 in |
416 | ms => next_task (map (Graph.get_node G) ms, Graph.del_nodes ms G)); |
415 if not (null finished) then next_task (Graph.del_nodes (map fst finished) G) |
|
416 else if null tasks then ((Task.Finished, I), G) |
|
417 else |
|
418 (case find_first (not o Task.is_running o snd) tasks of |
|
419 NONE => ((Task.Running, I), G) |
|
420 | SOME (name, task) => |
|
421 ((task, Graph.del_nodes [name]), Graph.map_node name (K Task.Running) G)) |
|
422 end; |
417 |
423 |
418 fun schedule_tasks (tasks, n) = |
424 fun schedule_tasks (tasks, n) = |
419 let val m = ! Multithreading.max_threads in |
425 let val m = ! Multithreading.max_threads in |
420 if m <= 1 orelse n <= 1 then schedule_seq tasks |
426 if m <= 1 orelse n <= 1 then schedule_seq tasks |
421 else if Multithreading.self_critical () then |
427 else if Multithreading.self_critical () then |
422 (warning (loader_msg "no multithreading within critical section" []); |
428 (warning (loader_msg "no multithreading within critical section" []); |
423 schedule_seq tasks) |
429 schedule_seq tasks) |
424 else |
430 else |
425 (case Multithreading.schedule (Int.min (m, n)) next_task ([], tasks) of |
431 (case Multithreading.schedule (Int.min (m, n)) next_task tasks of |
426 [] => () |
432 [] => () |
427 | exns => raise Exn.EXCEPTIONS (exns, "")) |
433 | exns => raise Exn.EXCEPTIONS (exns, "")) |
428 end; |
434 end; |
429 |
435 |
430 fun gen_use_thy' req dir arg = Output.toplevel_errors (fn () => |
436 fun gen_use_thy' req dir arg = Output.toplevel_errors (fn () => |