diff --git a/vlib/runtime/used_memory_darwin.c.v b/vlib/runtime/used_memory_darwin.c.v new file mode 100644 index 0000000000..5a20cf3fd0 --- /dev/null +++ b/vlib/runtime/used_memory_darwin.c.v @@ -0,0 +1,17 @@ +module runtime + +struct C.task_basic_info { + resident_size u64 +} + +fn C.task_info(C.task_t, int, &C.task_basic_info, &u64) int + +// used_memory retrieves the current physical memory usage of the process. +pub fn used_memory() !u64 { + mut info := C.task_basic_info{} + mut count := u64(C.MACH_TASK_BASIC_INFO_COUNT) + if C.task_info(C.mach_task_self(), C.TASK_BASIC_INFO, &info, &count) == C.KERN_SUCCESS { + return info.resident_size + } + return 0 +} diff --git a/vlib/runtime/used_memory_default.c.v b/vlib/runtime/used_memory_default.c.v new file mode 100644 index 0000000000..baada77895 --- /dev/null +++ b/vlib/runtime/used_memory_default.c.v @@ -0,0 +1,6 @@ +module runtime + +// used_memory retrieves the current physical memory usage of the process. +pub fn used_memory() !u64 { + return error('`used_memory()` not implemented') +} diff --git a/vlib/runtime/used_memory_linux.c.v b/vlib/runtime/used_memory_linux.c.v new file mode 100644 index 0000000000..19b5a5d92f --- /dev/null +++ b/vlib/runtime/used_memory_linux.c.v @@ -0,0 +1,19 @@ +module runtime + +import os + +// used_memory retrieves the current physical memory usage of the process. +pub fn used_memory() !u64 { + file := '/proc/self/status' + content := os.read_file(file) or { return 0 } + for line in content.split_into_lines() { + if line.starts_with('VmRSS:') { + parts := line.split(':') + if parts.len > 1 { + value := parts[1].trim_space().replace('kB', '').trim_space() + return value.u64() * 1024 // Convert to bytes + } + } + } + return 0 +} diff --git a/vlib/runtime/used_memory_test.v b/vlib/runtime/used_memory_test.v new file mode 100644 index 0000000000..24580fdf40 --- /dev/null +++ b/vlib/runtime/used_memory_test.v @@ -0,0 +1,21 @@ +import runtime + +fn test_used_memory() { + used1 := runtime.used_memory()! + println('used memory 1 : ${used1}') + + mut mem1 := unsafe { malloc(4096 * 1024) } + unsafe { vmemset(mem1, 1, 4096 * 1024) } + + used2 := runtime.used_memory()! + println('used memory 2 : ${used2}') + + mut mem2 := unsafe { malloc(8192 * 1024) } + unsafe { vmemset(mem2, 1, 8192 * 1024) } + + used3 := runtime.used_memory()! + println('used memory 3 : ${used3}') + assert used1 > 0 + assert used2 > used1 + assert used3 > used2 +} diff --git a/vlib/runtime/used_memory_windows.c.v b/vlib/runtime/used_memory_windows.c.v new file mode 100644 index 0000000000..6aa9113edc --- /dev/null +++ b/vlib/runtime/used_memory_windows.c.v @@ -0,0 +1,22 @@ +module runtime + +#flag -lpsapi +#include + +@[typedef] +struct C.PROCESS_MEMORY_COUNTERS { + cb u64 + WorkingSetSize isize +} + +fn C.GetProcessMemoryInfo(int, &C.PROCESS_MEMORY_COUNTERS, u64) bool + +// used_memory retrieves the current physical memory usage of the process. +pub fn used_memory() !u64 { + mut pmc := C.PROCESS_MEMORY_COUNTERS{} + pmc.cb = u64(sizeof(pmc)) + if C.GetProcessMemoryInfo(C.GetCurrentProcess(), &pmc, pmc.cb) { + return u64(pmc.WorkingSetSize) + } + return 0 +}