src/Pure/Concurrent/isabelle_thread.ML
author wenzelm
Wed, 06 Sep 2023 14:09:27 +0200
changeset 78648 852ec09aef13
parent 78647 27380538d632
child 78650 47d0c333d155
permissions -rw-r--r--
more explicit type Isabelle_Thread.T; total operation Isabelle_Thread.self: upgrade raw ML threads implicitly;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71692
f8e52c0152fe clarified names;
wenzelm
parents: 64557
diff changeset
     1
(*  Title:      Pure/Concurrent/isabelle_thread.ML
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
     3
71692
f8e52c0152fe clarified names;
wenzelm
parents: 64557
diff changeset
     4
Isabelle-specific thread management.
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
     5
*)
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
     6
71692
f8e52c0152fe clarified names;
wenzelm
parents: 64557
diff changeset
     7
signature ISABELLE_THREAD =
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
     8
sig
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
     9
  type T
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    10
  val get_thread: T -> Thread.thread
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    11
  val get_name: T -> string
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    12
  val get_id: T -> int
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    13
  val equal: T * T -> bool
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    14
  val print: T -> string
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    15
  val self: unit -> T
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    16
  val is_self: T -> bool
71883
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    17
  val stack_limit: unit -> int option
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    18
  type params = {name: string, stack_limit: int option, interrupts: bool}
59468
fe6651760643 explicit threads_stack_limit (for recent Poly/ML SVN versions), which leads to soft interrupt instead of exhaustion of virtual memory, which is particularly relevant for the bigger address space of x86_64;
wenzelm
parents: 59055
diff changeset
    19
  val attributes: params -> Thread.threadAttribute list
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    20
  val fork: params -> (unit -> unit) -> T
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    21
  val is_active: T -> bool
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    22
  val join: T -> unit
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    23
  val interrupt_unsynchronized: T -> unit
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
    24
end;
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
    25
71692
f8e52c0152fe clarified names;
wenzelm
parents: 64557
diff changeset
    26
structure Isabelle_Thread: ISABELLE_THREAD =
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
    27
struct
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
    28
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    29
(* abstract type *)
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    30
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    31
abstype T = T of {thread: Thread.thread, name: string, id: int}
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    32
with
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    33
  val make = T;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    34
  fun dest (T args) = args;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    35
end;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    36
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    37
val get_thread = #thread o dest;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    38
val get_name = #name o dest;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    39
val get_id = #id o dest;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    40
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    41
val equal = Thread.equal o apply2 get_thread;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    42
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    43
fun print t =
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    44
  (case get_name t of "" => "ML" | a => "Isabelle." ^ a) ^
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    45
    "-" ^ string_of_int (get_id t);
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    46
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    47
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    48
(* self *)
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    49
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    50
val make_id = Counter.make ();
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    51
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    52
local
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    53
  val self_var = Thread_Data.var () : T Thread_Data.var;
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    54
in
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    55
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    56
fun set_self t = Thread_Data.put self_var (SOME t);
60830
f56e189350b2 separate channel for debugger output;
wenzelm
parents: 60829
diff changeset
    57
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    58
fun self () =
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    59
  (case Thread_Data.get self_var of
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    60
    SOME t => t
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    61
  | NONE =>
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    62
      let val t = make {thread = Thread.self (), name = "", id = make_id ()}
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    63
      in set_self t; t end);
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    64
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    65
fun is_self t = equal (t, self ());
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    66
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    67
end;
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    68
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    69
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    70
(* fork *)
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    71
71883
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    72
fun stack_limit () =
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    73
  let
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    74
    val threads_stack_limit =
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    75
      Real.floor (Options.default_real "threads_stack_limit" * 1024.0 * 1024.0 * 1024.0);
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    76
  in if threads_stack_limit <= 0 then NONE else SOME threads_stack_limit end;
44ba78056790 clarified signature;
wenzelm
parents: 71694
diff changeset
    77
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    78
type params = {name: string, stack_limit: int option, interrupts: bool};
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    79
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    80
fun attributes ({stack_limit, interrupts, ...}: params) =
62501
98fa1f9a292f discontinued polyml-5.3.0;
wenzelm
parents: 61556
diff changeset
    81
  Thread.MaximumMLStack stack_limit ::
64557
37074e22e8be more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents: 62923
diff changeset
    82
  Thread_Attributes.convert_attributes
37074e22e8be more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents: 62923
diff changeset
    83
    (if interrupts then Thread_Attributes.public_interrupts else Thread_Attributes.no_interrupts);
59468
fe6651760643 explicit threads_stack_limit (for recent Poly/ML SVN versions), which leads to soft interrupt instead of exhaustion of virtual memory, which is particularly relevant for the bigger address space of x86_64;
wenzelm
parents: 59055
diff changeset
    84
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    85
fun fork (params: params) body =
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    86
  let
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    87
    val name = #name params;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    88
    val id = make_id ();
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    89
    fun main () = (set_self (make {thread = Thread.self (), name = name, id = id}); body ());
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    90
    val thread = Thread.fork (main, attributes params);
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    91
  in make {thread = thread, name = name, id = id} end;
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
    92
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    93
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    94
(* join *)
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
    95
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    96
val is_active = Thread.isActive o get_thread;
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    97
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    98
fun join t =
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
    99
  while is_active t
52583
0a7240d88e09 explicit shutdown of message output thread;
wenzelm
parents: 49894
diff changeset
   100
  do OS.Process.sleep (seconds 0.1);
0a7240d88e09 explicit shutdown of message output thread;
wenzelm
parents: 49894
diff changeset
   101
60764
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
   102
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
   103
(* interrupt *)
b610ba36e02c more explicit thread identification;
wenzelm
parents: 59468
diff changeset
   104
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
   105
fun interrupt_unsynchronized t =
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 78647
diff changeset
   106
  Thread.interrupt (get_thread t) handle Thread _ => ();
28550
422e9bd169ac added fail-safe interrupt;
wenzelm
parents: 28241
diff changeset
   107
28241
de20fccf6509 Simplified thread fork interface.
wenzelm
parents:
diff changeset
   108
end;