# HG changeset patch # User wenzelm # Date 1186696431 -7200 # Node ID 8a2c8d623e43b4eb22550b26e6087c99352c96ec # Parent f4cafbaa05e49152b83581c3352fcb165e82072d schedule: misc cleanup, more precise task model; diff -r f4cafbaa05e4 -r 8a2c8d623e43 src/Pure/Thy/thy_info.ML --- a/src/Pure/Thy/thy_info.ML Thu Aug 09 23:53:50 2007 +0200 +++ b/src/Pure/Thy/thy_info.ML Thu Aug 09 23:53:51 2007 +0200 @@ -325,6 +325,55 @@ end; +(* scheduling loader tasks *) + +datatype task = Task of (unit -> unit) | Finished | Running; +fun task_finished Finished = true | task_finished _ = false; + +local + +fun max_task (name, (Task body, m)) NONE = SOME (name, (body, m)) + | max_task (name, (Task body, m)) (task' as SOME (_, (_, m'))) = + if m > m' then SOME (name, (body, m)) else task' + | max_task _ task' = task'; + +fun next_task G = + let + val tasks = Graph.minimals G |> map (fn name => + (name, (Graph.get_node G name, length (Graph.imm_succs G name)))); + val finished = filter (task_finished o fst o snd) tasks; + in + if not (null finished) then next_task (Graph.del_nodes (map fst finished) G) + else if null tasks then (Multithreading.Terminate, G) + else + (case fold max_task tasks NONE of + NONE => (Multithreading.Wait, G) + | SOME (name, (body, _)) => + (Multithreading.Task {body = body, cont = Graph.del_nodes [name], fail = K Graph.empty}, + Graph.map_node name (K Running) G)) + end; + +fun schedule_seq tasks = + Graph.topological_order tasks + |> List.app (fn name => (case Graph.get_node tasks name of Task body => body () | _ => ())); + +in + +fun schedule_tasks tasks n = + let val m = ! Multithreading.max_threads in + if m <= 1 orelse n <= 1 then schedule_seq tasks + else if Multithreading.self_critical () then + (warning (loader_msg "no multithreading within critical section" []); + schedule_seq tasks) + else + (case Multithreading.schedule (Int.min (m, n)) next_task tasks of + [] => () + | exns => raise Exn.EXCEPTIONS (exns, "")) + end; + +end; + + (* require_thy -- checking database entries wrt. the file-system *) local @@ -374,7 +423,7 @@ val _ = member (op =) initiators name andalso error (cycle_msg initiators); in (case try (Graph.get_node (fst tasks)) name of - SOME task => (Task.is_finished task, tasks) + SOME task => (task_finished task, tasks) | NONE => let val (current, deps, parents) = check_deps dir' name @@ -394,8 +443,8 @@ val upd_time = serial (); val tasks_graph'' = tasks_graph' |> new_deps name parent_names - (if all_current then Task.Finished - else Task.Task (fn () => load_thy time upd_time initiators dir' name)); + (if all_current then Finished + else Task (fn () => load_thy time upd_time initiators dir' name)); val tasks_len'' = if all_current then tasks_len' else tasks_len' + 1; in (all_current, (tasks_graph'', tasks_len'')) end) end; @@ -403,49 +452,13 @@ end; -(* variations on use_thy -- scheduling required theories *) +(* use_thy etc. *) local -fun schedule_seq tasks = - Graph.topological_order tasks - |> List.app (fn name => (case Graph.get_node tasks name of Task.Task f => f () | _ => ())); - -fun max_task (task as (_, (Task.Task _, _: int))) NONE = SOME task - | max_task (task as (_, (Task.Task _, m))) (task' as SOME (_, (_, m'))) = - if m > m' then SOME task else task' - | max_task _ task' = task'; - -fun next_task G = - let - val tasks = Graph.minimals G |> map (fn name => - (name, (Graph.get_node G name, length (Graph.imm_succs G name)))); - val finished = filter (Task.is_finished o fst o snd) tasks; - in - if not (null finished) then next_task (Graph.del_nodes (map fst finished) G) - else if null tasks then ((Task.Finished, I), G) - else - (case fold max_task tasks NONE of - NONE => ((Task.Running, I), G) - | SOME (name, (task, _)) => - ((task, Graph.del_nodes [name]), Graph.map_node name (K Task.Running) G)) - end; - -fun schedule_tasks (tasks, n) = - let val m = ! Multithreading.max_threads in - if m <= 1 orelse n <= 1 then schedule_seq tasks - else if Multithreading.self_critical () then - (warning (loader_msg "no multithreading within critical section" []); - schedule_seq tasks) - else - (case Multithreading.schedule (Int.min (m, n)) next_task tasks of - [] => () - | exns => raise Exn.EXCEPTIONS (exns, "")) - end; - fun gen_use_thy' req dir arg = - let val (_, tasks) = req [] dir arg (Graph.empty, 0) - in schedule_tasks tasks end; + let val (_, (tasks, n)) = req [] dir arg (Graph.empty, 0) + in schedule_tasks tasks n end; fun gen_use_thy req str = let val name = base_name str in @@ -458,7 +471,6 @@ val use_thys_dir = gen_use_thy' (require_thys false); val use_thys = use_thys_dir Path.current; - val use_thy = gen_use_thy (require_thy false); val time_use_thy = gen_use_thy (require_thy true);