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