src/Pure/Concurrent/multithreading.scala
author wenzelm
Thu, 15 Feb 2024 09:53:58 +0100
changeset 79613 7a432595fb66
parent 79607 118504de9d0d
child 79650 65ef68bab8d6
permissions -rw-r--r--
more robust defaults;

/*  Title:      Pure/Concurrent/multithreading.scala
    Author:     Makarius

Multithreading in Isabelle/Scala.
*/

package isabelle


object Multithreading {
  /* physical processors */

  // slightly different from Poly/ML (more accurate)
  def num_processors(ssh: SSH.System = SSH.Local): Int =
    if (ssh.isabelle_platform.is_macos) {
      val result = ssh.execute("sysctl -n hw.physicalcpu").check
      Library.trim_line(result.out) match {
        case Value.Int(n) => n max 1
        case _ => 1
      }
    }
    else {
      val Physical = """^\s*physical id\s*:\s*(\d+)\s*$""".r
      val Cores = """^\s*cpu cores\s*:\s*(\d+)\s*$""".r

      var physical: Option[Int] = None
      var physical_cores = Map.empty[Int, Int]

      val result = ssh.execute("cat /proc/cpuinfo").check
      for (line <- Library.trim_split_lines(result.out)) {
        line match {
          case Physical(Value.Int(i)) => physical = Some(i)
          case Cores(Value.Int(i))
            if physical.isDefined && !physical_cores.isDefinedAt(physical.get) =>
            physical_cores = physical_cores + (physical.get -> i)
          case _ =>
        }
      }
      physical_cores.valuesIterator.sum max 1
    }


  /* max_threads */

  def max_threads(): Int = {
    val m = Value.Int.unapply(System.getProperty("isabelle.threads", "0")) getOrElse 0
    if (m > 0) m else num_processors() min 8
  }
}