This commit is contained in:
devdatt 2026-01-18 03:52:48 +05:30
parent cf36fbfe71
commit b88c2876b7
1 changed files with 60 additions and 42 deletions

View File

@ -7,6 +7,22 @@ if (!file_exists($coreFile)) {
file_put_contents($coreFile, json_encode([])); file_put_contents($coreFile, json_encode([]));
} }
function getNumaTopology(): array
{
$out = shell_exec("numactl --hardware");
$nodes = [];
foreach (explode("\n", $out) as $line) {
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;
}
}
return $nodes;
}
/* Get total CPU cores */ /* Get total CPU cores */
function getTotalCores(): int function getTotalCores(): int
{ {
@ -14,69 +30,66 @@ function getTotalCores(): int
} }
/* Allocate next free core */ /* Allocate next free core */
function allocateCore(int $serviceId): int function allocateCore(int $serviceId): array
{ {
global $coreFile; global $coreFile;
$map = json_decode(file_get_contents($coreFile), true) ?: []; $map = json_decode(file_get_contents($coreFile), true) ?: [];
$total = getTotalCores(); $usedCores = array_column($map, 'cpu');
if ($total < 2) { $nodes = getNumaTopology();
$map[$serviceId] = 0; $nodeIds = array_keys($nodes);
$nodeCount = count($nodeIds);
/* Alternate NUMA nodes */
$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)); file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
return 0; return $map[$serviceId];
}
$half = intdiv($total, 2);
/*
Build desired order:
0, half, 1, half+1, 2, half+2, ...
*/
$order = [];
for ($i = 0; $i < $half; $i++) {
$order[] = $i;
if (($i + $half) < $total) {
$order[] = $i + $half;
} }
} }
$used = array_values($map); /* Fallback: any free CPU */
foreach ($nodes as $n => $cpus) {
foreach ($order as $core) { foreach ($cpus as $cpu) {
if (!in_array($core, $used, true)) { if (!in_array($cpu, $usedCores, true)) {
$map[$serviceId] = $core; $map[$serviceId] = ["node" => $n, "cpu" => $cpu];
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT)); file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
return $core; return $map[$serviceId];
}
} }
} }
/* Fallback (should never hit unless fully occupied) */ /* Absolute fallback */
$core = $order[count($map) % count($order)]; return ["node" => 0, "cpu" => 0];
$map[$serviceId] = $core;
file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
return $core;
} }
/* Free core on delete */ /* Free core on delete */
function freeCore(int $serviceId): void function freeCore(int $serviceId): void
{ {
global $coreFile; global $coreFile;
$map = json_decode(file_get_contents($coreFile), true) ?: [];
$cores = json_decode(file_get_contents($coreFile), true); if (isset($map[$serviceId])) {
if (isset($cores[$serviceId])) { unset($map[$serviceId]);
unset($cores[$serviceId]); file_put_contents($coreFile, json_encode($map, JSON_PRETTY_PRINT));
file_put_contents($coreFile, json_encode($cores, JSON_PRETTY_PRINT));
} }
} }
/* Get assigned core */ /* Get assigned core */
function getServiceCore(int $serviceId): ?int function getServiceCore(int $serviceId): ?array
{ {
global $coreFile; global $coreFile;
$map = json_decode(file_get_contents($coreFile), true) ?: [];
$cores = json_decode(file_get_contents($coreFile), true); return $map[$serviceId] ?? null;
return $cores[$serviceId] ?? null;
} }
$jsonFile = __DIR__ . "/input.json"; $jsonFile = __DIR__ . "/input.json";
@ -111,9 +124,14 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $_POST["action"] === "add") {
$data[] = $new; $data[] = $new;
file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT)); file_put_contents($jsonFile, json_encode($data, JSON_PRETTY_PRINT));
$core = allocateCore($new["id"]);
$ffmpeg = 'taskset -c ' . $core . ' ffmpeg -hide_banner -loglevel info \ $alloc = allocateCore($id);
$node = $alloc["node"];
$core = $alloc["cpu"];
$ffmpeg = 'numactl --cpunodebind=' . $node .
' --membind=' . $node .
' taskset -c ' . $core . ' ffmpeg -hide_banner -loglevel info \
-thread_queue_size 65536 \ -thread_queue_size 65536 \
-fflags +genpts+discardcorrupt+nobuffer \ -fflags +genpts+discardcorrupt+nobuffer \
-readrate 1.0 \ -readrate 1.0 \
@ -330,7 +348,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST" && $_POST["action"] === "restart") {
<div class="containerindex"> <div class="containerindex">
<div class="grid"> <div class="grid">
<div class="card wide"> <div class="card">
<h2>Service List</h2> <h2>Service List</h2>
<button onclick="openAddPopup()">Add Service</button> <button onclick="openAddPopup()">Add Service</button>