equal
deleted
inserted
replaced
36 |
36 |
37 lazy val numactl_available: Boolean = Isabelle_System.bash("numactl --hardware").ok |
37 lazy val numactl_available: Boolean = Isabelle_System.bash("numactl --hardware").ok |
38 |
38 |
39 def policy(node: Int): String = |
39 def policy(node: Int): String = |
40 if (numactl_available) "numactl -m" + node + " -N" + node else "" |
40 if (numactl_available) "numactl -m" + node + " -N" + node else "" |
|
41 |
|
42 |
|
43 /* shuffling of CPU nodes */ |
|
44 |
|
45 def enabled_warning(enabled: Boolean): Boolean = |
|
46 { |
|
47 def warning = |
|
48 if (nodes().length < 2) Some("no NUMA nodes available") |
|
49 else if (!numactl_available) Some("missing numactl tool") |
|
50 else None |
|
51 |
|
52 enabled && |
|
53 (warning match { |
|
54 case Some(s) => Output.warning("Shuffling of CPU nodes is disabled: " + s); false |
|
55 case _ => true |
|
56 }) |
|
57 } |
|
58 |
|
59 class Nodes(enabled: Boolean = true) |
|
60 { |
|
61 private val available = nodes().zipWithIndex |
|
62 private var next_index = 0 |
|
63 |
|
64 def next(used: Int => Boolean = _ => false): Option[Int] = synchronized { |
|
65 if (!enabled || available.isEmpty) None |
|
66 else { |
|
67 val candidates = available.drop(next_index) ::: available.take(next_index) |
|
68 val (n, i) = |
|
69 candidates.find({ case (n, i) => i == next_index && !used(n) }) orElse |
|
70 candidates.find({ case (n, _) => !used(n) }) getOrElse candidates.head |
|
71 next_index = (i + 1) % available.length |
|
72 Some(n) |
|
73 } |
|
74 } |
|
75 } |
41 } |
76 } |