src/Pure/Concurrent/multithreading.ML
author wenzelm
Tue, 12 Mar 2024 15:57:25 +0100
changeset 79873 6c19c29ddcbe
parent 79613 7a432595fb66
permissions -rw-r--r--
clarified modules;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62508
d0b68218ea55 discontinued RAW session: bootstrap directly from isabelle_process RAW_ML_SYSTEM;
wenzelm
parents: 62501
diff changeset
     1
(*  Title:      Pure/Concurrent/multithreading.ML
24690
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
     3
79601
3430787e0620 tuned comments;
wenzelm
parents: 78720
diff changeset
     4
Multithreading in Poly/ML, see also
3430787e0620 tuned comments;
wenzelm
parents: 78720
diff changeset
     5
  - $ML_SOURCES/basis/Thread.sml: numPhysicalProcessors
3430787e0620 tuned comments;
wenzelm
parents: 78720
diff changeset
     6
  - $ML_SOURCES/libpolyml/processes.cpp: PolyThreadNumPhysicalProcessors
24690
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
     7
*)
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
     8
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
     9
signature MULTITHREADING =
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    10
sig
79604
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    11
  val num_processors: unit -> int
62925
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    12
  val max_threads: unit -> int
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    13
  val max_threads_update: int -> unit
68025
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    14
  val parallel_proofs: int ref
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    15
  val sync_wait: Time.time option -> Thread.ConditionVar.conditionVar -> Thread.Mutex.mutex ->
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    16
    bool Exn.result
39616
8052101883c3 renamed setmp_noncritical to Unsynchronized.setmp to emphasize its meaning;
wenzelm
parents: 32777
diff changeset
    17
  val trace: int ref
32295
400cc493d466 renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
wenzelm
parents: 32286
diff changeset
    18
  val tracing: int -> (unit -> string) -> unit
400cc493d466 renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
wenzelm
parents: 32286
diff changeset
    19
  val tracing_time: bool -> Time.time -> (unit -> string) -> unit
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    20
  val synchronized: string -> Thread.Mutex.mutex -> (unit -> 'a) -> 'a
24690
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    21
end;
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    22
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    23
structure Multithreading: MULTITHREADING =
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    24
struct
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    25
79604
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    26
(* physical processors *)
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    27
62501
98fa1f9a292f discontinued polyml-5.3.0;
wenzelm
parents: 62359
diff changeset
    28
fun num_processors () =
79613
7a432595fb66 more robust defaults;
wenzelm
parents: 79604
diff changeset
    29
  Int.max
7a432595fb66 more robust defaults;
wenzelm
parents: 79604
diff changeset
    30
    (case Thread.Thread.numPhysicalProcessors () of
7a432595fb66 more robust defaults;
wenzelm
parents: 79604
diff changeset
    31
      SOME n => n
7a432595fb66 more robust defaults;
wenzelm
parents: 79604
diff changeset
    32
    | NONE => Thread.Thread.numProcessors (), 1);
62501
98fa1f9a292f discontinued polyml-5.3.0;
wenzelm
parents: 62359
diff changeset
    33
79604
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    34
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    35
(* max_threads *)
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    36
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    37
local
0e8ac7db1f4d clarified num_processors: follow Poly/ML (with its inaccuracies);
wenzelm
parents: 79601
diff changeset
    38
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    39
fun max_threads_result m =
62926
9ff9bcbc2341 virtual Pure is single-threaded to avoid confusion with multiple thread farms etc.;
wenzelm
parents: 62925
diff changeset
    40
  if Thread_Data.is_virtual then 1
9ff9bcbc2341 virtual Pure is single-threaded to avoid confusion with multiple thread farms etc.;
wenzelm
parents: 62925
diff changeset
    41
  else if m > 0 then m
79613
7a432595fb66 more robust defaults;
wenzelm
parents: 79604
diff changeset
    42
  else Int.min (num_processors (), 8);
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    43
62925
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    44
val max_threads_state = ref 1;
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    45
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    46
in
32286
1fb5db48002d added Multithreading.sync_wait, which turns enabled interrupts to sync ones, to ensure that wait will reaquire its lock when interrupted;
wenzelm
parents: 32186
diff changeset
    47
62925
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    48
fun max_threads () = ! max_threads_state;
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    49
fun max_threads_update m = max_threads_state := max_threads_result m;
67659
11b390e971f6 clarified signature;
wenzelm
parents: 64563
diff changeset
    50
62925
f1bdf10f95d8 tuned signature;
wenzelm
parents: 62924
diff changeset
    51
end;
28187
4062882c7df3 proper values of no_interrupts, regular_interrupts;
wenzelm
parents: 28169
diff changeset
    52
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    53
68025
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    54
(* parallel_proofs *)
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    55
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    56
val parallel_proofs = ref 1;
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    57
7fb7a6366a40 clarified modules;
wenzelm
parents: 67659
diff changeset
    58
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    59
(* synchronous wait *)
41713
a21084741b37 added Multithreading.interrupted (cf. java.lang.Thread.interrupted);
wenzelm
parents: 39616
diff changeset
    60
64276
622f4e4ac388 eliminated unused argument;
wenzelm
parents: 62927
diff changeset
    61
fun sync_wait time cond lock =
62923
3a122e1e352a clarified bootstrap;
wenzelm
parents: 62918
diff changeset
    62
  Thread_Attributes.with_attributes
64557
37074e22e8be more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
wenzelm
parents: 64276
diff changeset
    63
    (Thread_Attributes.sync_interrupts (Thread_Attributes.get_attributes ()))
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    64
    (fn _ =>
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    65
      (case time of
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    66
        SOME t => Exn.Res (Thread.ConditionVar.waitUntil (cond, lock, t))
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    67
      | NONE => (Thread.ConditionVar.wait (cond, lock); Exn.Res true))
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    68
      handle exn => Exn.Exn exn);
32295
400cc493d466 renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
wenzelm
parents: 32286
diff changeset
    69
400cc493d466 renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
wenzelm
parents: 32286
diff changeset
    70
400cc493d466 renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
wenzelm
parents: 32286
diff changeset
    71
(* tracing *)
30612
cb6421b6a18f future_job: do not inherit attributes, but enforce restricted interrupts -- attempt to prevent interrupt race conditions;
wenzelm
parents: 29564
diff changeset
    72
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    73
val trace = ref 0;
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    74
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    75
fun tracing level msg =
64562
wenzelm
parents: 64557
diff changeset
    76
  if ! trace < level then ()
78720
909dc00766a0 clarified signature;
wenzelm
parents: 78716
diff changeset
    77
  else Thread_Attributes.uninterruptible_body (fn _ =>
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    78
    (TextIO.output (TextIO.stdErr, (">>> " ^ msg () ^ "\n")); TextIO.flushOut TextIO.stdErr)
78720
909dc00766a0 clarified signature;
wenzelm
parents: 78716
diff changeset
    79
      handle _ (*sic*) => ());
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    80
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    81
fun tracing_time detailed time =
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    82
  tracing
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    83
   (if not detailed then 5
62826
eb94e570c1a4 prefer infix operations;
wenzelm
parents: 62715
diff changeset
    84
    else if time >= seconds 1.0 then 1
eb94e570c1a4 prefer infix operations;
wenzelm
parents: 62715
diff changeset
    85
    else if time >= seconds 0.1 then 2
eb94e570c1a4 prefer infix operations;
wenzelm
parents: 62715
diff changeset
    86
    else if time >= seconds 0.01 then 3
eb94e570c1a4 prefer infix operations;
wenzelm
parents: 62715
diff changeset
    87
    else if time >= seconds 0.001 then 4 else 5);
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    88
25735
4d147263f71f added get/put_data;
wenzelm
parents: 25704
diff changeset
    89
59180
c0fa3b3bdabd discontinued central critical sections: NAMED_CRITICAL / CRITICAL;
wenzelm
parents: 59054
diff changeset
    90
(* synchronized evaluation *)
24690
c661dae1070a renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
wenzelm
parents:
diff changeset
    91
62359
6709e51d5c11 unconditional Multithreading;
wenzelm
parents: 61925
diff changeset
    92
fun synchronized name lock e =
78720
909dc00766a0 clarified signature;
wenzelm
parents: 78716
diff changeset
    93
  Exn.release (Thread_Attributes.uninterruptible_body (fn run =>
64563
wenzelm
parents: 64562
diff changeset
    94
    if ! trace > 0 then
wenzelm
parents: 64562
diff changeset
    95
      let
wenzelm
parents: 64562
diff changeset
    96
        val immediate =
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
    97
          if Thread.Mutex.trylock lock then true
64563
wenzelm
parents: 64562
diff changeset
    98
          else
wenzelm
parents: 64562
diff changeset
    99
            let
wenzelm
parents: 64562
diff changeset
   100
              val _ = tracing 5 (fn () => name ^ ": locking ...");
wenzelm
parents: 64562
diff changeset
   101
              val timer = Timer.startRealTimer ();
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
   102
              val _ = Thread.Mutex.lock lock;
64563
wenzelm
parents: 64562
diff changeset
   103
              val time = Timer.checkRealTimer timer;
wenzelm
parents: 64562
diff changeset
   104
              val _ = tracing_time true time (fn () => name ^ ": locked after " ^ Time.toString time);
wenzelm
parents: 64562
diff changeset
   105
            in false end;
78716
97dfba4405e3 tuned signature;
wenzelm
parents: 78715
diff changeset
   106
        val result = Exn.capture0 (run e) ();
64563
wenzelm
parents: 64562
diff changeset
   107
        val _ = if immediate then () else tracing 5 (fn () => name ^ ": unlocking ...");
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
   108
        val _ = Thread.Mutex.unlock lock;
64563
wenzelm
parents: 64562
diff changeset
   109
      in result end
wenzelm
parents: 64562
diff changeset
   110
    else
wenzelm
parents: 64562
diff changeset
   111
      let
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
   112
        val _ = Thread.Mutex.lock lock;
78716
97dfba4405e3 tuned signature;
wenzelm
parents: 78715
diff changeset
   113
        val result = Exn.capture0 (run e) ();
78650
47d0c333d155 clarified signature: retain original Poly/ML names Thread.Thread, Thread.Mutex, Thread.ConditionVar and de-emphasize them for Isabelle/ML;
wenzelm
parents: 68130
diff changeset
   114
        val _ = Thread.Mutex.unlock lock;
78720
909dc00766a0 clarified signature;
wenzelm
parents: 78716
diff changeset
   115
      in result end));
59054
61b723761dff load simple_thread.ML later, such that it benefits from redefined print_exception_trace;
wenzelm
parents: 54717
diff changeset
   116
28123
53cd972d7db9 provide dummy thread structures, including proper Thread.getLocal/setLocal;
wenzelm
parents: 26082
diff changeset
   117
end;