src/Pure/Concurrent/task_queue.ML
author wenzelm
Mon, 08 Sep 2008 21:08:30 +0200
changeset 28171 9b2f9cc9ff4b
parent 28168 ba410235ff04
child 28176 01b21886e7f0
permissions -rw-r--r--
proper signature constraint;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/Concurrent/task_queue.ML
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     2
    ID:         $Id$
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     3
    Author:     Makarius
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     4
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     5
Ordered queue of grouped tasks.
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     6
*)
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     7
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     8
signature TASK_QUEUE =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
     9
sig
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    10
  eqtype task
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    11
  eqtype group
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    12
  val new_group: unit -> group
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    13
  type queue
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    14
  val empty: queue
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    15
  val enqueue: group option -> task list -> (unit -> bool) -> queue -> task * queue
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    16
  val dequeue: Thread.thread -> queue -> (task * group option * (unit -> bool)) option * queue
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    17
  val finished: task -> queue -> queue
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    18
  val interrupt_task: queue -> task -> unit
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    19
  val interrupt_group: queue -> group -> unit
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    20
  val interrupt_task_group: queue -> task -> unit
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    21
end;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    22
28171
9b2f9cc9ff4b proper signature constraint;
wenzelm
parents: 28168
diff changeset
    23
structure TaskQueue: TASK_QUEUE =
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    24
struct
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    25
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    26
(* identifiers *)
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    27
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    28
datatype task = Task of serial;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    29
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    30
datatype group = Group of serial;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    31
fun new_group () = Group (serial ());
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    32
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    33
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    34
(* queue of dependent jobs *)
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    35
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    36
datatype job =
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    37
  Job of unit -> bool |
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    38
  Running of Thread.thread;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    39
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    40
datatype queue = Queue of
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    41
  {jobs: (group option * job) IntGraph.T,                         (*job dependency graph*)
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    42
   cache: (task * group option * (unit -> bool)) Queue.T option,  (*cache of ready tasks*)
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    43
   groups: task list Inttab.table};                               (*active group members*)
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    44
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    45
fun make_queue jobs cache groups =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    46
  Queue {jobs = jobs, cache = cache, groups = groups};
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    47
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    48
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    49
(* queue operations *)
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    50
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    51
val empty = make_queue IntGraph.empty NONE Inttab.empty;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    52
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    53
fun enqueue group deps job (Queue {jobs, groups, ...}) =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    54
  let
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    55
    val id = serial ();
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    56
    val task = Task id;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    57
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    58
    fun add_dep (Task dep) G = IntGraph.add_edge_acyclic (dep, id) G
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    59
      handle IntGraph.UNDEF _ => G;
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    60
    val jobs' = jobs |> IntGraph.new_node (id, (group, Job job)) |> fold add_dep deps;
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    61
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    62
    val groups' =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    63
      (case group of
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    64
        NONE => groups
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    65
      | SOME (Group gid) => Inttab.cons_list (gid, task) groups);
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    66
  in (task, make_queue jobs' NONE groups') end;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    67
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    68
fun dequeue thread (queue as Queue {jobs, cache, groups}) =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    69
  let
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    70
    val ready =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    71
      (case cache of
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    72
        SOME ready => ready
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    73
      | NONE =>
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    74
          let
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    75
            fun add (id, ((group, Job job), ([], _))) = Queue.enqueue (Task id, group, job)
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    76
              | add _ = I;
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    77
          in IntGraph.fold add jobs Queue.empty end);
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    78
  in
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    79
    if Queue.is_empty ready then (NONE, make_queue jobs (SOME ready) groups)
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    80
    else
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    81
      let
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    82
        val (result as (Task id, _, _), ready') = Queue.dequeue ready;
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    83
        val jobs' = IntGraph.map_node id (fn (group, _) => (group, Running thread)) jobs;
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    84
      in (SOME result, make_queue jobs' (SOME ready') groups) end
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    85
  end;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    86
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    87
fun finished (task as Task id) (Queue {jobs, groups, ...}) =
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    88
  let
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    89
    val groups' =
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    90
      (case #1 (IntGraph.get_node jobs id) of
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    91
        NONE => groups
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    92
      | SOME (Group gid) => Inttab.remove_list (op =) (gid, task) groups);
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    93
    val jobs' = IntGraph.del_nodes [id] jobs;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    94
  in make_queue jobs' NONE groups' end;
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    95
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    96
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    97
(* interrupt *)
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
    98
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
    99
fun interrupt_task (Queue {jobs, ...}) (Task id) =
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   100
  (case IntGraph.get_node jobs id of
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   101
    (_, Running thread) => (Thread.interrupt thread handle Thread _ => ())
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   102
  | _ => ())
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   103
  handle IntGraph.UNDEF _ => ();
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   104
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   105
fun interrupt_group (queue as Queue {groups, ...}) (Group gid) =
28168
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   106
  List.app (interrupt_task queue) (Inttab.lookup_list groups gid);
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   107
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   108
fun interrupt_task_group (queue as Queue {jobs, ...}) (task as Task id) =
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   109
  (case IntGraph.get_node jobs id of
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   110
    (NONE, _) => interrupt_task queue task
ba410235ff04 moved thread data to future.ML (again);
wenzelm
parents: 28165
diff changeset
   111
  | (SOME group, _) => interrupt_group queue group);
28165
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   112
26bb048f463c Ordered queue of grouped tasks.
wenzelm
parents:
diff changeset
   113
end;