| author | haftmann | 
| Thu, 05 Aug 2021 07:12:49 +0000 | |
| changeset 74122 | 7d3e818fe21f | 
| parent 71883 | 44ba78056790 | 
| child 78647 | 27380538d632 | 
| permissions | -rw-r--r-- | 
| 71692 | 1 | (* Title: Pure/Concurrent/isabelle_thread.ML | 
| 28241 | 2 | Author: Makarius | 
| 3 | ||
| 71692 | 4 | Isabelle-specific thread management. | 
| 28241 | 5 | *) | 
| 6 | ||
| 71692 | 7 | signature ISABELLE_THREAD = | 
| 28241 | 8 | sig | 
| 49894 
69bfd86cc711
more robust cancel_now: avoid shooting yourself in the foot;
 wenzelm parents: 
44112diff
changeset | 9 | val is_self: Thread.thread -> bool | 
| 71694 | 10 | val get_name: unit -> string | 
| 71883 | 11 | val stack_limit: unit -> int option | 
| 60764 | 12 |   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: 
59055diff
changeset | 13 | val attributes: params -> Thread.threadAttribute list | 
| 
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: 
59055diff
changeset | 14 | val fork: params -> (unit -> unit) -> Thread.thread | 
| 52583 | 15 | val join: Thread.thread -> unit | 
| 44112 
ef876972fdc1
more explicit Simple_Thread.interrupt_unsynchronized, to emphasize its meaning;
 wenzelm parents: 
40232diff
changeset | 16 | val interrupt_unsynchronized: Thread.thread -> unit | 
| 28241 | 17 | end; | 
| 18 | ||
| 71692 | 19 | structure Isabelle_Thread: ISABELLE_THREAD = | 
| 28241 | 20 | struct | 
| 21 | ||
| 60764 | 22 | (* self *) | 
| 23 | ||
| 49894 
69bfd86cc711
more robust cancel_now: avoid shooting yourself in the foot;
 wenzelm parents: 
44112diff
changeset | 24 | fun is_self thread = Thread.equal (Thread.self (), thread); | 
| 
69bfd86cc711
more robust cancel_now: avoid shooting yourself in the foot;
 wenzelm parents: 
44112diff
changeset | 25 | |
| 60764 | 26 | |
| 60829 | 27 | (* unique name *) | 
| 60764 | 28 | |
| 29 | local | |
| 62889 | 30 | val name_var = Thread_Data.var () : string Thread_Data.var; | 
| 60764 | 31 | val count = Counter.make (); | 
| 32 | in | |
| 33 | ||
| 71694 | 34 | fun get_name () = | 
| 35 | (case Thread_Data.get name_var of | |
| 36 | SOME name => name | |
| 37 | | NONE => raise Fail "Isabelle-specific thread required"); | |
| 60830 | 38 | |
| 39 | fun set_name base = | |
| 71693 | 40 |   Thread_Data.put name_var (SOME ("Isabelle." ^ base ^ "-" ^ string_of_int (count ())));
 | 
| 60764 | 41 | |
| 42 | end; | |
| 43 | ||
| 44 | ||
| 45 | (* fork *) | |
| 46 | ||
| 71883 | 47 | fun stack_limit () = | 
| 48 | let | |
| 49 | val threads_stack_limit = | |
| 50 | Real.floor (Options.default_real "threads_stack_limit" * 1024.0 * 1024.0 * 1024.0); | |
| 51 | in if threads_stack_limit <= 0 then NONE else SOME threads_stack_limit end; | |
| 52 | ||
| 60764 | 53 | type params = {name: string, stack_limit: int option, interrupts: bool};
 | 
| 54 | ||
| 55 | fun attributes ({stack_limit, interrupts, ...}: params) =
 | |
| 62501 | 56 | Thread.MaximumMLStack stack_limit :: | 
| 64557 
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
 wenzelm parents: 
62923diff
changeset | 57 | Thread_Attributes.convert_attributes | 
| 
37074e22e8be
more tight thread attributes, based in internal word arithmetic instead of symbolic datatypes: measurable performance improvement;
 wenzelm parents: 
62923diff
changeset | 58 | (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: 
59055diff
changeset | 59 | |
| 60764 | 60 | fun fork (params: params) body = | 
| 39232 
69c6d3e87660
more abstract treatment of interrupts in structure Exn -- hardly ever need to mention Interrupt literally;
 wenzelm parents: 
37216diff
changeset | 61 | Thread.fork (fn () => | 
| 62505 | 62 | Exn.trace General.exnMessage tracing (fn () => | 
| 60829 | 63 | (set_name (#name params); body ()) | 
| 62505 | 64 | handle exn => if Exn.is_interrupt exn then () (*sic!*) else Exn.reraise exn), | 
| 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: 
59055diff
changeset | 65 | attributes params); | 
| 28241 | 66 | |
| 60764 | 67 | |
| 68 | (* join *) | |
| 69 | ||
| 52583 | 70 | fun join thread = | 
| 71 | while Thread.isActive thread | |
| 72 | do OS.Process.sleep (seconds 0.1); | |
| 73 | ||
| 60764 | 74 | |
| 75 | (* interrupt *) | |
| 76 | ||
| 77 | fun interrupt_unsynchronized thread = | |
| 78 | Thread.interrupt thread handle Thread _ => (); | |
| 28550 | 79 | |
| 28241 | 80 | end; |