summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshiya Hinosawa <stibium121@gmail.com>2023-11-30 22:06:01 +0900
committerGitHub <noreply@github.com>2023-11-30 22:06:01 +0900
commit3591ba8578b5eff96c13afc6fdfcf95a96083761 (patch)
tree087723f0e357df08e6254a440749a53b5c588444
parent595a2be024b3523197557a8b122e3ce77f1dae3c (diff)
fix(ext/node): fix os.freemem (#21347)
-rw-r--r--cli/tests/unit_node/os_test.ts20
-rw-r--r--ext/node/polyfills/os.ts9
-rw-r--r--runtime/ops/os/README.md2
-rw-r--r--runtime/ops/os/sys_info.rs12
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")]
{