src/Pure/Thy/thy_info.ML
changeset 23982 e3c4c0b9ae05
parent 23974 16ecf0a5a6bb
child 24057 f42665561801
equal deleted inserted replaced
23981:03b71bf91318 23982:e3c4c0b9ae05
    47 end;
    47 end;
    48 
    48 
    49 structure ThyInfo: THY_INFO =
    49 structure ThyInfo: THY_INFO =
    50 struct
    50 struct
    51 
    51 
    52 
       
    53 (** theory loader actions and hooks **)
    52 (** theory loader actions and hooks **)
    54 
    53 
    55 datatype action = Update | Outdate | Remove;
    54 datatype action = Update | Outdate | Remove;
    56 val str_of_action = fn Update => "Update" | Outdate => "Outdate" | Remove => "Remove";
    55 val str_of_action = fn Update => "Update" | Outdate => "Outdate" | Remove => "Remove";
    57 
    56 
   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 () =>