From 412827dc0a2e783cf036bfb03a48eb9eb0f9193b Mon Sep 17 00:00:00 2001 From: robobun <117481402+robobun@users.noreply.github.com> Date: Tue, 14 Jul 2026 01:07:25 +0000 Subject: [PATCH] WTF: add uv_get_cgroup_current_memory() Reads the process's cgroup's current memory usage (memory.current on cgroup v2, memory.usage_in_bytes on cgroup v1), reusing the existing uv__slurp, uv__read_uint64 and uv__cgroup1_find_memory_controller helpers that uv_get_constrained_memory() already uses. Matches libuv's uv__get_cgroup_current_memory. Bun needs this for process.availableMemory(): Node.js documents that API as uv_get_available_memory(), which on Linux returns (cgroup limit - cgroup current usage) when a limit is set. The limit reader already exists here; this adds the usage reader so bun can compute the difference without duplicating the cgroup parsing. --- Source/WTF/wtf/uv_get_constrained_memory.cpp | 50 ++++++++++++++++++++ Source/WTF/wtf/uv_get_constrained_memory.h | 1 + 2 files changed, 51 insertions(+) diff --git a/Source/WTF/wtf/uv_get_constrained_memory.cpp b/Source/WTF/wtf/uv_get_constrained_memory.cpp index 57f3748c9bc85..f69f0742fce0e 100644 --- a/Source/WTF/wtf/uv_get_constrained_memory.cpp +++ b/Source/WTF/wtf/uv_get_constrained_memory.cpp @@ -259,6 +259,51 @@ uint64_t uv_get_constrained_memory() return uv__get_cgroup_constrained_memory(buf); } +static uint64_t uv__get_cgroup1_current_memory(char buf[1024]) +{ + char filename[4097]; + char* p; + int n; + + p = uv__cgroup1_find_memory_controller(buf, &n); + if (p != NULL) { + snprintf(filename, sizeof(filename), + "/sys/fs/cgroup/memory/%.*s/memory.usage_in_bytes", n, p); + uint64_t current = uv__read_uint64(filename); + if (current != 0) + return current; + } + + return uv__read_uint64("/sys/fs/cgroup/memory/memory.usage_in_bytes"); +} + +static uint64_t uv__get_cgroup2_current_memory(char buf[1024]) +{ + char filename[4097]; + char* p; + int n; + + p = buf + strlen("0::/"); + n = (int)strcspn(p, "\n"); + + snprintf(filename, sizeof(filename), + "/sys/fs/cgroup/%.*s/memory.current", n, p); + return uv__read_uint64(filename); +} + +uint64_t uv_get_cgroup_current_memory() +{ + char buf[1024]; + + if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf))) + return 0; + + if (strncmp(buf, "0::/", 4)) + return uv__get_cgroup1_current_memory(buf); + + return uv__get_cgroup2_current_memory(buf); +} + /* Find the cgroup v1 line whose controller list contains "cpu" as a whole * token (it may appear as "cpu", "cpu,cpuacct", or "cpuacct,cpu"). Returns * a pointer to the path component (after the leading "/") and its length. */ @@ -376,6 +421,11 @@ uint64_t uv_get_constrained_memory() return 0; } +uint64_t uv_get_cgroup_current_memory() +{ + return 0; +} + int uv_get_constrained_cpu() { return 0; diff --git a/Source/WTF/wtf/uv_get_constrained_memory.h b/Source/WTF/wtf/uv_get_constrained_memory.h index 2ae999118c340..06977e8f3d17a 100644 --- a/Source/WTF/wtf/uv_get_constrained_memory.h +++ b/Source/WTF/wtf/uv_get_constrained_memory.h @@ -1,4 +1,5 @@ #pragma once uint64_t uv_get_constrained_memory(); +uint64_t uv_get_cgroup_current_memory(); int uv_get_constrained_cpu(); \ No newline at end of file