8 |
8 |
9 |
9 |
10 import java.util.concurrent.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue} |
10 import java.util.concurrent.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue} |
11 |
11 |
12 |
12 |
13 object Isabelle_Thread |
13 object Isabelle_Thread { |
14 { |
|
15 /* self-thread */ |
14 /* self-thread */ |
16 |
15 |
17 def self: Isabelle_Thread = |
16 def self: Isabelle_Thread = |
18 Thread.currentThread match { |
17 Thread.currentThread match { |
19 case thread: Isabelle_Thread => thread |
18 case thread: Isabelle_Thread => thread |
26 |
25 |
27 /* create threads */ |
26 /* create threads */ |
28 |
27 |
29 private val counter = Counter.make() |
28 private val counter = Counter.make() |
30 |
29 |
31 def make_name(name: String = "", base: String = "thread"): String = |
30 def make_name(name: String = "", base: String = "thread"): String = { |
32 { |
|
33 val prefix = "Isabelle." |
31 val prefix = "Isabelle." |
34 val suffix = if (name.nonEmpty) name else base + counter() |
32 val suffix = if (name.nonEmpty) name else base + counter() |
35 if (suffix.startsWith(prefix)) suffix else prefix + suffix |
33 if (suffix.startsWith(prefix)) suffix else prefix + suffix |
36 } |
34 } |
37 |
35 |
44 main: Runnable, |
42 main: Runnable, |
45 name: String = "", |
43 name: String = "", |
46 group: ThreadGroup = current_thread_group, |
44 group: ThreadGroup = current_thread_group, |
47 pri: Int = Thread.NORM_PRIORITY, |
45 pri: Int = Thread.NORM_PRIORITY, |
48 daemon: Boolean = false, |
46 daemon: Boolean = false, |
49 inherit_locals: Boolean = false): Isabelle_Thread = |
47 inherit_locals: Boolean = false |
50 { |
48 ): Isabelle_Thread = { |
51 new Isabelle_Thread(main, name = make_name(name = name), group = group, |
49 new Isabelle_Thread(main, name = make_name(name = name), group = group, |
52 pri = pri, daemon = daemon, inherit_locals = inherit_locals) |
50 pri = pri, daemon = daemon, inherit_locals = inherit_locals) |
53 } |
51 } |
54 |
52 |
55 def fork( |
53 def fork( |
56 name: String = "", |
54 name: String = "", |
57 group: ThreadGroup = current_thread_group, |
55 group: ThreadGroup = current_thread_group, |
58 pri: Int = Thread.NORM_PRIORITY, |
56 pri: Int = Thread.NORM_PRIORITY, |
59 daemon: Boolean = false, |
57 daemon: Boolean = false, |
60 inherit_locals: Boolean = false, |
58 inherit_locals: Boolean = false, |
61 uninterruptible: Boolean = false)(body: => Unit): Isabelle_Thread = |
59 uninterruptible: Boolean = false)( |
62 { |
60 body: => Unit |
|
61 ): Isabelle_Thread = { |
63 val main: Runnable = |
62 val main: Runnable = |
64 if (uninterruptible) { () => Isabelle_Thread.uninterruptible { body } } |
63 if (uninterruptible) { () => Isabelle_Thread.uninterruptible { body } } |
65 else { () => body } |
64 else { () => body } |
66 val thread = |
65 val thread = |
67 create(main, name = name, group = group, pri = pri, |
66 create(main, name = name, group = group, pri = pri, |
71 } |
70 } |
72 |
71 |
73 |
72 |
74 /* thread pool */ |
73 /* thread pool */ |
75 |
74 |
76 def max_threads(): Int = |
75 def max_threads(): Int = { |
77 { |
|
78 val m = Value.Int.unapply(System.getProperty("isabelle.threads", "0")) getOrElse 0 |
76 val m = Value.Int.unapply(System.getProperty("isabelle.threads", "0")) getOrElse 0 |
79 if (m > 0) m else (Runtime.getRuntime.availableProcessors max 1) min 8 |
77 if (m > 0) m else (Runtime.getRuntime.availableProcessors max 1) min 8 |
80 } |
78 } |
81 |
79 |
82 lazy val pool: ThreadPoolExecutor = |
80 lazy val pool: ThreadPoolExecutor = { |
83 { |
|
84 val n = max_threads() |
81 val n = max_threads() |
85 val executor = |
82 val executor = |
86 new ThreadPoolExecutor(n, n, 2500L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue[Runnable]) |
83 new ThreadPoolExecutor(n, n, 2500L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue[Runnable]) |
87 executor.setThreadFactory( |
84 executor.setThreadFactory( |
88 create(_, name = make_name(base = "worker"), group = worker_thread_group)) |
85 create(_, name = make_name(base = "worker"), group = worker_thread_group)) |
90 } |
87 } |
91 |
88 |
92 |
89 |
93 /* interrupt handlers */ |
90 /* interrupt handlers */ |
94 |
91 |
95 object Interrupt_Handler |
92 object Interrupt_Handler { |
96 { |
|
97 def apply(handle: Isabelle_Thread => Unit, name: String = "handler"): Interrupt_Handler = |
93 def apply(handle: Isabelle_Thread => Unit, name: String = "handler"): Interrupt_Handler = |
98 new Interrupt_Handler(handle, name) |
94 new Interrupt_Handler(handle, name) |
99 |
95 |
100 val interruptible: Interrupt_Handler = |
96 val interruptible: Interrupt_Handler = |
101 Interrupt_Handler(_.raise_interrupt, name = "interruptible") |
97 Interrupt_Handler(_.raise_interrupt, name = "interruptible") |
103 val uninterruptible: Interrupt_Handler = |
99 val uninterruptible: Interrupt_Handler = |
104 Interrupt_Handler(_.postpone_interrupt, name = "uninterruptible") |
100 Interrupt_Handler(_.postpone_interrupt, name = "uninterruptible") |
105 } |
101 } |
106 |
102 |
107 class Interrupt_Handler private(handle: Isabelle_Thread => Unit, name: String) |
103 class Interrupt_Handler private(handle: Isabelle_Thread => Unit, name: String) |
108 extends Function[Isabelle_Thread, Unit] |
104 extends Function[Isabelle_Thread, Unit] { |
109 { |
|
110 def apply(thread: Isabelle_Thread): Unit = handle(thread) |
105 def apply(thread: Isabelle_Thread): Unit = handle(thread) |
111 override def toString: String = name |
106 override def toString: String = name |
112 } |
107 } |
113 |
108 |
114 def interrupt_handler[A](handler: Interrupt_Handler)(body: => A): A = |
109 def interrupt_handler[A](handler: Interrupt_Handler)(body: => A): A = |
129 else body |
124 else body |
130 } |
125 } |
131 |
126 |
132 class Isabelle_Thread private(main: Runnable, name: String, group: ThreadGroup, |
127 class Isabelle_Thread private(main: Runnable, name: String, group: ThreadGroup, |
133 pri: Int, daemon: Boolean, inherit_locals: Boolean) |
128 pri: Int, daemon: Boolean, inherit_locals: Boolean) |
134 extends Thread(group, null, name, 0L, inherit_locals) |
129 extends Thread(group, null, name, 0L, inherit_locals) { |
135 { |
|
136 thread => |
130 thread => |
137 |
131 |
138 thread.setPriority(pri) |
132 thread.setPriority(pri) |
139 thread.setDaemon(daemon) |
133 thread.setDaemon(daemon) |
140 |
134 |