diff --git a/html/input.php b/html/input.php index 1147342..460d464 100644 --- a/html/input.php +++ b/html/input.php @@ -16,63 +16,59 @@ function getNumaTopology(): array if (preg_match('/node (\d+) cpus:\s+(.*)/', $line, $m)) { $node = (int)$m[1]; $cpus = array_map('intval', preg_split('/\s+/', trim($m[2]))); - $nodes[$node] = $cpus; + + /* use EVEN CPUs only: 0,2,4,... */ + $nodes[$node] = array_values( + array_filter($cpus, fn($c) => $c % 2 === 0) + ); } } + ksort($nodes); // ensure deterministic order return $nodes; } -/* Get total CPU cores */ -function getTotalCores(): int -{ - return intval(trim(shell_exec("nproc"))); -} - -/* Allocate next free core */ +/* Allocate core in strict round-robin */ function allocateCore(int $serviceId): array { global $coreFile; $map = json_decode(file_get_contents($coreFile), true) ?: []; - $usedCores = array_column($map, 'cpu'); - $nodes = getNumaTopology(); - $nodeIds = array_keys($nodes); - $nodeCount = count($nodeIds); - /* Alternate NUMA nodes */ + $nodeIds = array_keys($nodes); + $nodeCount = count($nodeIds); // ✅ calculated BEFORE processing + + if ($nodeCount === 0) { + return ["node" => 0, "cpu" => 0]; + } + $index = count($map); - $node = $nodeIds[$index % $nodeCount]; - foreach ($nodes[$node] as $cpu) { - if (!in_array($cpu, $usedCores, true)) { - $map[$serviceId] = [ - "node" => $node, - "cpu" => $cpu - ]; - file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT)); - return $map[$serviceId]; - } + /* Round-robin node selection */ + $nodePos = $index % $nodeCount; + $node = $nodeIds[$nodePos]; + + /* Per-node CPU index */ + $cpuIndex = intdiv($index, $nodeCount); + + /* Wrap safely if CPUs exhausted */ + if (!isset($nodes[$node][$cpuIndex])) { + $cpuIndex = $cpuIndex % count($nodes[$node]); } - /* Fallback: any free CPU */ - foreach ($nodes as $n => $cpus) { - foreach ($cpus as $cpu) { - if (!in_array($cpu, $usedCores, true)) { - $map[$serviceId] = ["node" => $n, "cpu" => $cpu]; - file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT)); - return $map[$serviceId]; - } - } - } + $cpu = $nodes[$node][$cpuIndex]; - /* Absolute fallback */ - return ["node" => 0, "cpu" => 0]; + $map[$serviceId] = [ + "node" => $node, + "cpu" => $cpu + ]; + + file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT)); + return $map[$serviceId]; } - -/* Free core on delete */ +/* Free core */ function freeCore(int $serviceId): void { global $coreFile;