src/Pure/System/numa.scala
changeset 64265 8eb6365f5916
parent 64264 42138702d6ec
child 64497 f6cefd465f86
--- a/src/Pure/System/numa.scala	Sun Oct 16 20:19:10 2016 +0200
+++ b/src/Pure/System/numa.scala	Sun Oct 16 22:43:51 2016 +0200
@@ -38,4 +38,39 @@
 
   def policy(node: Int): String =
     if (numactl_available) "numactl -m" + node + " -N" + node else ""
+
+
+  /* shuffling of CPU nodes */
+
+  def enabled_warning(enabled: Boolean): Boolean =
+  {
+    def warning =
+      if (nodes().length < 2) Some("no NUMA nodes available")
+      else if (!numactl_available) Some("missing numactl tool")
+      else None
+
+    enabled &&
+      (warning match {
+        case Some(s) => Output.warning("Shuffling of CPU nodes is disabled: " + s); false
+        case _ => true
+      })
+  }
+
+  class Nodes(enabled: Boolean = true)
+  {
+    private val available = nodes().zipWithIndex
+    private var next_index = 0
+
+    def next(used: Int => Boolean = _ => false): Option[Int] = synchronized {
+      if (!enabled || available.isEmpty) None
+      else {
+        val candidates = available.drop(next_index) ::: available.take(next_index)
+        val (n, i) =
+          candidates.find({ case (n, i) => i == next_index && !used(n) }) orElse
+            candidates.find({ case (n, _) => !used(n) }) getOrElse candidates.head
+        next_index = (i + 1) % available.length
+        Some(n)
+      }
+    }
+  }
 }