diff options
author | Yoshiya Hinosawa <stibium121@gmail.com> | 2023-11-30 22:06:01 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-30 22:06:01 +0900 |
commit | 3591ba8578b5eff96c13afc6fdfcf95a96083761 (patch) | |
tree | 087723f0e357df08e6254a440749a53b5c588444 | |
parent | 595a2be024b3523197557a8b122e3ce77f1dae3c (diff) |
fix(ext/node): fix os.freemem (#21347)
-rw-r--r-- | cli/tests/unit_node/os_test.ts | 20 | ||||
-rw-r--r-- | ext/node/polyfills/os.ts | 9 | ||||
-rw-r--r-- | runtime/ops/os/README.md | 2 | ||||
-rw-r--r-- | runtime/ops/os/sys_info.rs | 12 |
4 files changed, 41 insertions, 2 deletions
diff --git a/cli/tests/unit_node/os_test.ts b/cli/tests/unit_node/os_test.ts index 2d0d3a8c8..54dc375bb 100644 --- a/cli/tests/unit_node/os_test.ts +++ b/cli/tests/unit_node/os_test.ts @@ -289,3 +289,23 @@ Deno.test({ await child.status; }, }); + +Deno.test({ + name: + "os.freemem() is equivalent of Deno.systemMemoryInfo().free except on linux", + ignore: Deno.build.os === "linux", + fn() { + const diff = Math.abs(os.freemem() - Deno.systemMemoryInfo().free); + assert(diff < 10_000); + }, +}); + +Deno.test({ + name: + "os.freemem() is equivalent of Deno.systemMemoryInfo().available on linux", + ignore: Deno.build.os !== "linux", + fn() { + const diff = Math.abs(os.freemem() - Deno.systemMemoryInfo().available); + assert(diff < 10_000); + }, +}); diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 06de4ad44..d1f5e7bfa 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -159,7 +159,14 @@ export function endianness(): "BE" | "LE" { /** Return free memory amount */ export function freemem(): number { - return Deno.systemMemoryInfo().free; + if (Deno.build.os === "linux") { + // On linux, use 'available' memory + // https://github.com/libuv/libuv/blob/a5c01d4de3695e9d9da34cfd643b5ff0ba582ea7/src/unix/linux.c#L2064 + return Deno.systemMemoryInfo().available; + } else { + // Use 'free' memory on other platforms + return Deno.systemMemoryInfo().free; + } } /** Not yet implemented */ diff --git a/runtime/ops/os/README.md b/runtime/ops/os/README.md index 837bb7b3c..ae1a5958e 100644 --- a/runtime/ops/os/README.md +++ b/runtime/ops/os/README.md @@ -27,6 +27,6 @@ | Target family | Syscall | Description | | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | -| Linux | sysinfo | - | +| Linux | sysinfo and `/proc/meminfo` | - | | Windows | `sysinfoapi::GlobalMemoryStatusEx` | - | | macOS | <br> <pre> sysctl([CTL_HW, HW_MEMSIZE]); <br> sysctl([CTL_VM, VM_SWAPUSAGE]); <br> host_statistics64(mach_host_self(), HOST_VM_INFO64) </pre> | - | diff --git a/runtime/ops/os/sys_info.rs b/runtime/ops/os/sys_info.rs index d8175f31b..b3d2cd743 100644 --- a/runtime/ops/os/sys_info.rs +++ b/runtime/ops/os/sys_info.rs @@ -211,8 +211,20 @@ pub fn mem_info() -> Option<MemInfo> { mem_info.swap_free = info.freeswap * mem_unit; mem_info.total = info.totalram * mem_unit; mem_info.free = info.freeram * mem_unit; + mem_info.available = mem_info.free; mem_info.buffers = info.bufferram * mem_unit; } + + // Gets the available memory from /proc/meminfo in linux for compatibility + #[allow(clippy::disallowed_methods)] + if let Ok(meminfo) = std::fs::read_to_string("/proc/meminfo") { + let line = meminfo.lines().find(|l| l.starts_with("MemAvailable:")); + if let Some(line) = line { + let mem = line.split_whitespace().nth(1); + let mem = mem.and_then(|v| v.parse::<u64>().ok()); + mem_info.available = mem.unwrap_or(0); + } + } } #[cfg(target_vendor = "apple")] { |