| author | wenzelm | 
| Sat, 10 Oct 2020 21:45:58 +0200 | |
| changeset 72428 | b7351ffe0dbc | 
| parent 68130 | 6fb85346cb79 | 
| child 78650 | 47d0c333d155 | 
| permissions | -rw-r--r-- | 
| 62508 
d0b68218ea55
discontinued RAW session: bootstrap directly from isabelle_process RAW_ML_SYSTEM;
 wenzelm parents: 
62501diff
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 | |
| 62359 | 4 | Multithreading in Poly/ML (cf. polyml/basis/Thread.sml). | 
| 24690 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 5 | *) | 
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 6 | |
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 7 | signature MULTITHREADING = | 
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 8 | sig | 
| 62925 | 9 | val max_threads: unit -> int | 
| 62359 | 10 | val max_threads_update: int -> unit | 
| 68025 | 11 | val parallel_proofs: int ref | 
| 64276 | 12 | val sync_wait: Time.time option -> ConditionVar.conditionVar -> Mutex.mutex -> bool Exn.result | 
| 39616 
8052101883c3
renamed setmp_noncritical to Unsynchronized.setmp to emphasize its meaning;
 wenzelm parents: 
32777diff
changeset | 13 | val trace: int ref | 
| 32295 
400cc493d466
renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
 wenzelm parents: 
32286diff
changeset | 14 | val tracing: int -> (unit -> string) -> unit | 
| 
400cc493d466
renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
 wenzelm parents: 
32286diff
changeset | 15 | val tracing_time: bool -> Time.time -> (unit -> string) -> unit | 
| 59054 
61b723761dff
load simple_thread.ML later, such that it benefits from redefined print_exception_trace;
 wenzelm parents: 
54717diff
changeset | 16 | val synchronized: string -> Mutex.mutex -> (unit -> 'a) -> 'a | 
| 24690 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 17 | end; | 
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 18 | |
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 19 | structure Multithreading: MULTITHREADING = | 
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 20 | struct | 
| 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 21 | |
| 62925 | 22 | (* max_threads *) | 
| 23 | ||
| 24 | local | |
| 62359 | 25 | |
| 62501 | 26 | fun num_processors () = | 
| 27 | (case Thread.numPhysicalProcessors () of | |
| 28 | SOME n => n | |
| 29 | | NONE => Thread.numProcessors ()); | |
| 30 | ||
| 62359 | 31 | fun max_threads_result m = | 
| 62926 
9ff9bcbc2341
virtual Pure is single-threaded to avoid confusion with multiple thread farms etc.;
 wenzelm parents: 
62925diff
changeset | 32 | if Thread_Data.is_virtual then 1 | 
| 
9ff9bcbc2341
virtual Pure is single-threaded to avoid confusion with multiple thread farms etc.;
 wenzelm parents: 
62925diff
changeset | 33 | else if m > 0 then m | 
| 
9ff9bcbc2341
virtual Pure is single-threaded to avoid confusion with multiple thread farms etc.;
 wenzelm parents: 
62925diff
changeset | 34 | else Int.min (Int.max (num_processors (), 1), 8); | 
| 62359 | 35 | |
| 62925 | 36 | val max_threads_state = ref 1; | 
| 37 | ||
| 38 | 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: 
32186diff
changeset | 39 | |
| 62925 | 40 | fun max_threads () = ! max_threads_state; | 
| 41 | fun max_threads_update m = max_threads_state := max_threads_result m; | |
| 67659 | 42 | |
| 62925 | 43 | end; | 
| 28187 
4062882c7df3
proper values of no_interrupts, regular_interrupts;
 wenzelm parents: 
28169diff
changeset | 44 | |
| 62359 | 45 | |
| 68025 | 46 | (* parallel_proofs *) | 
| 47 | ||
| 48 | val parallel_proofs = ref 1; | |
| 49 | ||
| 50 | ||
| 62359 | 51 | (* synchronous wait *) | 
| 41713 
a21084741b37
added Multithreading.interrupted (cf. java.lang.Thread.interrupted);
 wenzelm parents: 
39616diff
changeset | 52 | |
| 64276 | 53 | fun sync_wait time cond lock = | 
| 62923 | 54 | Thread_Attributes.with_attributes | 
| 64557 
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
 wenzelm parents: 
64276diff
changeset | 55 | (Thread_Attributes.sync_interrupts (Thread_Attributes.get_attributes ())) | 
| 62359 | 56 | (fn _ => | 
| 57 | (case time of | |
| 58 | SOME t => Exn.Res (ConditionVar.waitUntil (cond, lock, t)) | |
| 59 | | NONE => (ConditionVar.wait (cond, lock); Exn.Res true)) | |
| 60 | handle exn => Exn.Exn exn); | |
| 32295 
400cc493d466
renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
 wenzelm parents: 
32286diff
changeset | 61 | |
| 
400cc493d466
renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
 wenzelm parents: 
32286diff
changeset | 62 | |
| 
400cc493d466
renamed Multithreading.regular_interrupts to Multithreading.public_interrupts;
 wenzelm parents: 
32286diff
changeset | 63 | (* tracing *) | 
| 30612 
cb6421b6a18f
future_job: do not inherit attributes, but enforce restricted interrupts -- attempt to prevent interrupt race conditions;
 wenzelm parents: 
29564diff
changeset | 64 | |
| 62359 | 65 | val trace = ref 0; | 
| 66 | ||
| 67 | fun tracing level msg = | |
| 64562 | 68 | if ! trace < level then () | 
| 62923 | 69 | else Thread_Attributes.uninterruptible (fn _ => fn () => | 
| 62359 | 70 |     (TextIO.output (TextIO.stdErr, (">>> " ^ msg () ^ "\n")); TextIO.flushOut TextIO.stdErr)
 | 
| 71 | handle _ (*sic*) => ()) (); | |
| 72 | ||
| 73 | fun tracing_time detailed time = | |
| 74 | tracing | |
| 75 | (if not detailed then 5 | |
| 62826 | 76 | else if time >= seconds 1.0 then 1 | 
| 77 | else if time >= seconds 0.1 then 2 | |
| 78 | else if time >= seconds 0.01 then 3 | |
| 79 | else if time >= seconds 0.001 then 4 else 5); | |
| 62359 | 80 | |
| 25735 | 81 | |
| 59180 
c0fa3b3bdabd
discontinued central critical sections: NAMED_CRITICAL / CRITICAL;
 wenzelm parents: 
59054diff
changeset | 82 | (* synchronized evaluation *) | 
| 24690 
c661dae1070a
renamed ML-Systems/multithreading_dummy.ML to ML-Systems/multithreading.ML;
 wenzelm parents: diff
changeset | 83 | |
| 62359 | 84 | fun synchronized name lock e = | 
| 62923 | 85 | Exn.release (Thread_Attributes.uninterruptible (fn restore_attributes => fn () => | 
| 64563 | 86 | if ! trace > 0 then | 
| 87 | let | |
| 88 | val immediate = | |
| 89 | if Mutex.trylock lock then true | |
| 90 | else | |
| 91 | let | |
| 92 | val _ = tracing 5 (fn () => name ^ ": locking ..."); | |
| 93 | val timer = Timer.startRealTimer (); | |
| 94 | val _ = Mutex.lock lock; | |
| 95 | val time = Timer.checkRealTimer timer; | |
| 96 | val _ = tracing_time true time (fn () => name ^ ": locked after " ^ Time.toString time); | |
| 97 | in false end; | |
| 98 | val result = Exn.capture (restore_attributes e) (); | |
| 99 | val _ = if immediate then () else tracing 5 (fn () => name ^ ": unlocking ..."); | |
| 100 | val _ = Mutex.unlock lock; | |
| 101 | in result end | |
| 102 | else | |
| 103 | let | |
| 104 | val _ = Mutex.lock lock; | |
| 105 | val result = Exn.capture (restore_attributes e) (); | |
| 106 | val _ = Mutex.unlock lock; | |
| 107 | in result end) ()); | |
| 59054 
61b723761dff
load simple_thread.ML later, such that it benefits from redefined print_exception_trace;
 wenzelm parents: 
54717diff
changeset | 108 | |
| 28123 
53cd972d7db9
provide dummy thread structures, including proper Thread.getLocal/setLocal;
 wenzelm parents: 
26082diff
changeset | 109 | end; |