src/Pure/Concurrent/isabelle_thread.scala
changeset 75393 87ebf5a50283
parent 75380 2cb2606ce075
child 77409 d2711c9ffa51
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
     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