src/Pure/PIDE/execution.ML
author wenzelm
Tue, 05 Jun 2018 14:07:51 +0200
changeset 68379 1b0ce345d3c8
parent 68354 93d3c967802e
child 68880 8b98db8fd183
permissions -rw-r--r--
tuned;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52605
a2a805549c74 clarified module name;
wenzelm
parents: 52604
diff changeset
     1
(*  Title:      Pure/PIDE/execution.ML
52596
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
     3
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
     4
Global management of execution.  Unique running execution serves as
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
     5
barrier for further exploration of forked command execs.
52596
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
     6
*)
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
     7
52605
a2a805549c74 clarified module name;
wenzelm
parents: 52604
diff changeset
     8
signature EXECUTION =
52596
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
     9
sig
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    10
  val start: unit -> Document_ID.execution
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    11
  val discontinue: unit -> unit
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    12
  val is_running: Document_ID.execution -> bool
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    13
  val active_tasks: string -> Future.task list
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    14
  val worker_task_active: bool -> string -> unit
52784
4ba2e8b9972f de-assign execs that were not registered as running yet -- observe change of perspective more thoroughly;
wenzelm
parents: 52775
diff changeset
    15
  val is_running_exec: Document_ID.exec -> bool
53375
78693e46a237 Execution.fork formally requires registered Execution.running;
wenzelm
parents: 53193
diff changeset
    16
  val running: Document_ID.execution -> Document_ID.exec -> Future.group list -> bool
66370
de9c6560c221 more synchronized Execution.snapshot;
wenzelm
parents: 65948
diff changeset
    17
  val snapshot: Document_ID.exec list -> Future.task list
66371
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
    18
  val join: Document_ID.exec list -> unit
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
    19
  val peek: Document_ID.exec -> Future.group list
52655
3b2b1ef13979 more careful termination of removed execs, leaving running execs undisturbed;
wenzelm
parents: 52608
diff changeset
    20
  val cancel: Document_ID.exec -> unit
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
    21
  type params = {name: string, pos: Position.T, pri: int}
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
    22
  val fork: params -> (unit -> 'a) -> 'a future
56305
wenzelm
parents: 56304
diff changeset
    23
  val print: params -> (unit -> unit) -> unit
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
    24
  val fork_prints: Document_ID.exec -> unit
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
    25
  val purge: Document_ID.exec list -> unit
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
    26
  val reset: unit -> Future.group list
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
    27
  val shutdown: unit -> unit
52596
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
    28
end;
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
    29
52605
a2a805549c74 clarified module name;
wenzelm
parents: 52604
diff changeset
    30
structure Execution: EXECUTION =
52596
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
    31
struct
40298d383463 global management of command execution fragments;
wenzelm
parents:
diff changeset
    32
52787
c143ad7811fc pro-forma Execution.reset, despite lack of final join/commit;
wenzelm
parents: 52784
diff changeset
    33
(* global state *)
c143ad7811fc pro-forma Execution.reset, despite lack of final join/commit;
wenzelm
parents: 52784
diff changeset
    34
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
    35
type print = {name: string, pri: int, body: unit -> unit};
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    36
type execs = (Future.group list * print list) (*active forks, prints*) Inttab.table;
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    37
val init_execs: execs = Inttab.make [(Document_ID.none, ([], []))];
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    38
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    39
datatype state =
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    40
  State of
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    41
   {execution_id: Document_ID.execution,  (*overall document execution*)
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    42
    nodes: Future.task list Symtab.table,  (*active nodes*)
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    43
    execs: execs};  (*running command execs*)
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    44
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    45
fun make_state (execution_id, nodes, execs) =
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    46
  State {execution_id = execution_id, nodes = nodes, execs = execs};
52787
c143ad7811fc pro-forma Execution.reset, despite lack of final join/commit;
wenzelm
parents: 52784
diff changeset
    47
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    48
local
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    49
  val state =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    50
    Synchronized.var "Execution.state" (make_state (Document_ID.none, Symtab.empty, init_execs));
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    51
in
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    52
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    53
fun get_state () = let val State args = Synchronized.value state in args end;
52602
00170ef1dc39 strictly monotonic Document.update: avoid disruptive cancel_execution, merely discontinue_execution and cancel/terminate old execs individually;
wenzelm
parents: 52596
diff changeset
    54
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    55
fun change_state_result f =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    56
  Synchronized.change_result state (fn (State {execution_id, nodes, execs}) =>
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    57
    let val (result, args') = f (execution_id, nodes, execs)
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    58
    in (result, make_state args') end);
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    59
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    60
fun change_state f =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    61
  Synchronized.change state (fn (State {execution_id, nodes, execs}) =>
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    62
    make_state (f (execution_id, nodes, execs)));
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    63
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    64
end;
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
    65
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
    66
fun unregistered exec_id = "Unregistered execution: " ^ Document_ID.print exec_id;
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
    67
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    68
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    69
(* unique running execution *)
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    70
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    71
fun start () =
52602
00170ef1dc39 strictly monotonic Document.update: avoid disruptive cancel_execution, merely discontinue_execution and cancel/terminate old execs individually;
wenzelm
parents: 52596
diff changeset
    72
  let
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    73
    val execution_id = Document_ID.make ();
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    74
    val _ = change_state (fn (_, nodes, execs) => (execution_id, nodes, execs));
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    75
  in execution_id end;
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    76
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    77
fun discontinue () =
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    78
  change_state (fn (_, nodes, execs) => (Document_ID.none, nodes, execs));
52606
0d68d108d7e0 tuned signature;
wenzelm
parents: 52605
diff changeset
    79
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    80
fun is_running execution_id =
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
    81
  execution_id = #execution_id (get_state ());
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    82
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    83
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    84
(* active nodes *)
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    85
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    86
fun active_tasks node_name =
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    87
  Symtab.lookup_list (#nodes (get_state ())) node_name;
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    88
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    89
fun worker_task_active insert node_name =
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    90
  change_state (fn (execution_id, nodes, execs) =>
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    91
    let
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    92
      val nodes' = nodes
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    93
        |> (if insert then Symtab.insert_list else Symtab.remove_list)
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    94
          Task_Queue.eq_task (node_name, the (Future.worker_task ()));
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    95
    in (execution_id, nodes', execs) end);
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    96
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
    97
66371
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
    98
(* running execs *)
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
    99
52784
4ba2e8b9972f de-assign execs that were not registered as running yet -- observe change of perspective more thoroughly;
wenzelm
parents: 52775
diff changeset
   100
fun is_running_exec exec_id =
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
   101
  Inttab.defined (#execs (get_state ())) exec_id;
52784
4ba2e8b9972f de-assign execs that were not registered as running yet -- observe change of perspective more thoroughly;
wenzelm
parents: 52775
diff changeset
   102
53375
78693e46a237 Execution.fork formally requires registered Execution.running;
wenzelm
parents: 53193
diff changeset
   103
fun running execution_id exec_id groups =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   104
  change_state_result (fn (execution_id', nodes, execs) =>
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   105
    let
59348
8a6788917b32 do not crash into already running exec, instead join its lazy result in the subsequent step (amending 59f1591a11cb);
wenzelm
parents: 56333
diff changeset
   106
      val ok = execution_id = execution_id' andalso not (Inttab.defined execs exec_id);
8a6788917b32 do not crash into already running exec, instead join its lazy result in the subsequent step (amending 59f1591a11cb);
wenzelm
parents: 56333
diff changeset
   107
      val execs' = execs |> ok ? Inttab.update (exec_id, (groups, []));
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   108
    in (ok, (execution_id', nodes, execs')) end);
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   109
66371
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   110
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   111
(* exec groups and tasks *)
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   112
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
   113
fun exec_groups (execs: execs) exec_id =
66370
de9c6560c221 more synchronized Execution.snapshot;
wenzelm
parents: 65948
diff changeset
   114
  (case Inttab.lookup execs exec_id of
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   115
    SOME (groups, _) => groups
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   116
  | NONE => []);
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   117
68379
wenzelm
parents: 68354
diff changeset
   118
fun snapshot [] = []
wenzelm
parents: 68354
diff changeset
   119
  | snapshot exec_ids =
wenzelm
parents: 68354
diff changeset
   120
      change_state_result
wenzelm
parents: 68354
diff changeset
   121
        (`(fn (_, _, execs) => Future.snapshot (maps (exec_groups execs) exec_ids)));
66370
de9c6560c221 more synchronized Execution.snapshot;
wenzelm
parents: 65948
diff changeset
   122
66371
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   123
fun join exec_ids =
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   124
  (case snapshot exec_ids of
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   125
    [] => ()
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   126
  | tasks =>
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   127
      ((singleton o Future.forks)
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   128
        {name = "Execution.join", group = SOME (Future.new_group NONE),
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   129
          deps = tasks, pri = 0, interrupts = false} I
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   130
      |> Future.join; join exec_ids));
6ce1afc01040 more thorough Execution.join, under the assumption that nested Execution.fork only happens from given exed_ids;
wenzelm
parents: 66370
diff changeset
   131
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
   132
fun peek exec_id = exec_groups (#execs (get_state ())) exec_id;
66370
de9c6560c221 more synchronized Execution.snapshot;
wenzelm
parents: 65948
diff changeset
   133
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   134
fun cancel exec_id = List.app Future.cancel_group (peek exec_id);
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   135
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   136
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   137
(* fork *)
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   138
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   139
fun status task markups =
56296
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   140
  let
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   141
    val props =
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   142
      if ! Multithreading.trace >= 2
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   143
      then [(Markup.taskN, Task_Queue.str_of_task task)] else [];
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   144
  in Output.status (implode (map (Markup.markup_only o Markup.properties props) markups)) end;
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   145
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   146
type params = {name: string, pos: Position.T, pri: int};
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   147
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   148
fun fork ({name, pos, pri}: params) e =
62923
3a122e1e352a clarified bootstrap;
wenzelm
parents: 62891
diff changeset
   149
  Thread_Attributes.uninterruptible (fn _ => Position.setmp_thread_data pos (fn () =>
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   150
    let
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   151
      val exec_id = the_default 0 (Position.parse_id pos);
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   152
      val group = Future.worker_subgroup ();
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   153
      val _ = change_state (fn (execution_id, nodes, execs) =>
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   154
        (case Inttab.lookup execs exec_id of
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   155
          SOME (groups, prints) =>
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   156
            let val execs' = Inttab.update (exec_id, (group :: groups, prints)) execs
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   157
            in (execution_id, nodes, execs') end
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   158
        | NONE => raise Fail (unregistered exec_id)));
52655
3b2b1ef13979 more careful termination of removed execs, leaving running execs undisturbed;
wenzelm
parents: 52608
diff changeset
   159
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   160
      val future =
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   161
        (singleton o Future.forks)
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   162
          {name = name, group = SOME group, deps = [], pri = pri, interrupts = false}
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   163
          (fn () =>
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   164
            let
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   165
              val task = the (Future.worker_task ());
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   166
              val _ = status task [Markup.running];
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   167
              val result =
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   168
                Exn.capture (Future.interruptible_task e) ()
61077
06cca32aa519 thread context for exceptions from forks, e.g. relevant when printing errors;
wenzelm
parents: 59467
diff changeset
   169
                |> Future.identify_result pos
06cca32aa519 thread context for exceptions from forks, e.g. relevant when printing errors;
wenzelm
parents: 59467
diff changeset
   170
                |> Exn.map_exn Runtime.thread_context;
54646
2b38549374ba more robust status reports: avoid loosing information about physical events (see also 28d207ba9340, 2bc5924b117f, 9edfd36a0355) -- NB: TTY and Proof General ignore Output.status and Output.report;
wenzelm
parents: 53375
diff changeset
   171
              val _ = status task [Markup.joined];
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   172
              val _ =
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   173
                (case result of
54678
87910da843d5 more uniform status -- accommodate spurious Exn.Interrupt from user code, allow ML_Compiler.exn_messages_id to crash;
wenzelm
parents: 54646
diff changeset
   174
                  Exn.Exn exn =>
54646
2b38549374ba more robust status reports: avoid loosing information about physical events (see also 28d207ba9340, 2bc5924b117f, 9edfd36a0355) -- NB: TTY and Proof General ignore Output.status and Output.report;
wenzelm
parents: 53375
diff changeset
   175
                   (status task [Markup.failed];
54678
87910da843d5 more uniform status -- accommodate spurious Exn.Interrupt from user code, allow ML_Compiler.exn_messages_id to crash;
wenzelm
parents: 54646
diff changeset
   176
                    status task [Markup.finished];
64677
8dc24130e8fe more uniform treatment of "bad" like other messages (with serial number);
wenzelm
parents: 62923
diff changeset
   177
                    Output.report [Markup.markup_only (Markup.bad ())];
54646
2b38549374ba more robust status reports: avoid loosing information about physical events (see also 28d207ba9340, 2bc5924b117f, 9edfd36a0355) -- NB: TTY and Proof General ignore Output.status and Output.report;
wenzelm
parents: 53375
diff changeset
   178
                    if exec_id = 0 then ()
65948
de7888573ed7 clarified build errors;
wenzelm
parents: 64677
diff changeset
   179
                    else List.app (Future.error_message pos) (Runtime.exn_messages exn))
54678
87910da843d5 more uniform status -- accommodate spurious Exn.Interrupt from user code, allow ML_Compiler.exn_messages_id to crash;
wenzelm
parents: 54646
diff changeset
   180
                | Exn.Res _ =>
87910da843d5 more uniform status -- accommodate spurious Exn.Interrupt from user code, allow ML_Compiler.exn_messages_id to crash;
wenzelm
parents: 54646
diff changeset
   181
                    status task [Markup.finished])
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   182
            in Exn.release result end);
54646
2b38549374ba more robust status reports: avoid loosing information about physical events (see also 28d207ba9340, 2bc5924b117f, 9edfd36a0355) -- NB: TTY and Proof General ignore Output.status and Output.report;
wenzelm
parents: 53375
diff changeset
   183
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   184
      val _ = status (Future.task_of future) [Markup.forked];
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   185
    in future end)) ();
52604
ff2f0818aebc more explicit type Exec.context;
wenzelm
parents: 52602
diff changeset
   186
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   187
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   188
(* print *)
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   189
56305
wenzelm
parents: 56304
diff changeset
   190
fun print ({name, pos, pri}: params) e =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   191
  change_state (fn (execution_id, nodes, execs) =>
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   192
    let
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   193
      val exec_id = the_default 0 (Position.parse_id pos);
56305
wenzelm
parents: 56304
diff changeset
   194
      val print = {name = name, pri = pri, body = e};
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   195
    in
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   196
      (case Inttab.lookup execs exec_id of
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   197
        SOME (groups, prints) =>
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   198
          let val execs' = Inttab.update (exec_id, (groups, print :: prints)) execs
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   199
          in (execution_id, nodes, execs') end
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   200
      | NONE => raise Fail (unregistered exec_id))
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   201
    end);
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   202
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   203
fun fork_prints exec_id =
68353
29cbe9e8ecde tuned -- more explicit types;
wenzelm
parents: 68130
diff changeset
   204
  (case Inttab.lookup (#execs (get_state ())) exec_id of
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   205
    SOME (_, prints) =>
68130
6fb85346cb79 clarified future scheduling parameters, with support for parallel_limit;
wenzelm
parents: 67659
diff changeset
   206
      if Future.relevant prints then
56296
5413b6379c0e less markup by default -- this is stored persistently in Isabelle/Scala;
wenzelm
parents: 56292
diff changeset
   207
        let val pos = Position.thread_data () in
56292
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   208
          List.app (fn {name, pri, body} =>
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   209
            ignore (fork {name = name, pos = pos, pri = pri} body)) (rev prints)
1a91a0da65ab more uniform Execution.fork vs. Execution.print;
wenzelm
parents: 56291
diff changeset
   210
        end
67659
11b390e971f6 clarified signature;
wenzelm
parents: 66378
diff changeset
   211
      else List.app (fn {body, ...} => body ()) (rev prints)
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   212
  | NONE => raise Fail (unregistered exec_id));
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   213
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   214
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   215
(* cleanup *)
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   216
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   217
fun purge exec_ids =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   218
  change_state (fn (execution_id, nodes, execs) =>
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   219
    let
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   220
      val execs' = fold Inttab.delete_safe exec_ids execs;
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   221
      val () =
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   222
        (execs', ()) |-> Inttab.fold (fn (exec_id, (groups, _)) => fn () =>
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   223
          if Inttab.defined execs' exec_id then ()
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   224
          else groups |> List.app (fn group =>
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   225
            if Task_Queue.is_canceled group then ()
53375
78693e46a237 Execution.fork formally requires registered Execution.running;
wenzelm
parents: 53193
diff changeset
   226
            else raise Fail ("Attempt to purge valid execution: " ^ Document_ID.print exec_id)));
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   227
    in (execution_id, nodes, execs') end);
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   228
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   229
fun reset () =
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   230
  change_state_result (fn (_, _, execs) =>
56291
e79f76a48449 added Execution.print: accumulate print operations for some command execution, which are applied later and print time;
wenzelm
parents: 54678
diff changeset
   231
    let val groups = Inttab.fold (append o #1 o #2) execs []
68354
93d3c967802e record active execution task and depend on it -- avoid new executions bumping into old ones;
wenzelm
parents: 68353
diff changeset
   232
    in (groups, (Document_ID.none, Symtab.empty, init_execs)) end);
53192
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   233
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   234
fun shutdown () =
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   235
  (Future.shutdown ();
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   236
    (case maps Task_Queue.group_status (reset ()) of
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   237
      [] => ()
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   238
    | exns => raise Par_Exn.make exns));
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   239
04df1d236e1c maintain goal forks as part of global execution;
wenzelm
parents: 52787
diff changeset
   240
end;