From c3dfe62d7b3ee8bc288f943782644263e36bbbba Mon Sep 17 00:00:00 2001 From: Kim Shrier Date: Thu, 17 Jul 2025 01:14:01 -0600 Subject: [PATCH] runtime: add used_memory() implementation for FreeBSD (#24909) --- vlib/runtime/used_memory_default.c.v | 2 +- vlib/runtime/used_memory_freebsd.c.v | 62 ++++++++++++++++++++++++++++ vlib/runtime/used_memory_test.v | 17 ++++---- 3 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 vlib/runtime/used_memory_freebsd.c.v diff --git a/vlib/runtime/used_memory_default.c.v b/vlib/runtime/used_memory_default.c.v index 6d26ce20ab..afadb19d91 100644 --- a/vlib/runtime/used_memory_default.c.v +++ b/vlib/runtime/used_memory_default.c.v @@ -1,7 +1,7 @@ module runtime // used_memory retrieves the current physical memory usage of the process. -// Note: implementation available only on macOS, Linux and Windows. Otherwise, +// Note: implementation available only on FreeBSD, macOS, Linux and Windows. Otherwise, // returns 'used_memory: not implemented'. pub fn used_memory() !u64 { return error('used_memory: not implemented') diff --git a/vlib/runtime/used_memory_freebsd.c.v b/vlib/runtime/used_memory_freebsd.c.v new file mode 100644 index 0000000000..87506388b0 --- /dev/null +++ b/vlib/runtime/used_memory_freebsd.c.v @@ -0,0 +1,62 @@ +module runtime + +import os + +$if tinyc { + #include +} +struct C.rusage { + ru_maxrss int + ru_idrss int +} + +fn C.getrusage(who int, usage &C.rusage) int + +$if !tinyc { + #flag -lprocstat + + #include + #include +} +struct C.procstat {} + +struct C.kinfo_proc { + ki_rssize u64 +} + +fn C.procstat_open_sysctl() &C.procstat +fn C.procstat_close(&C.procstat) +fn C.procstat_getprocs(&C.procstat, int, int, &u32) &C.kinfo_proc + +// used_memory retrieves the current physical memory usage of the process. +pub fn used_memory() !u64 { + page_size := usize(C.sysconf(C._SC_PAGESIZE)) + c_errno_1 := C.errno + if page_size == usize(-1) { + return error('used_memory: C.sysconf() return error code = ${c_errno_1}') + } + $if tinyc { + mut usage := C.rusage{} + x := C.getrusage(0, &usage) + if x == -1 { + c_errno_2 := C.errno + return error('used_memory: C.getrusage() return error code = ${c_errno_2}') + } + return u64(int_max(1, usage.ru_maxrss)) * 1024 + } $else { + mut proc_status := C.procstat_open_sysctl() + defer { + C.procstat_close(proc_status) + } + + mut count := u32(0) + + kip := C.procstat_getprocs(proc_status, C.KERN_PROC_PID | C.KERN_PROC_INC_THREAD, + os.getpid(), &count) + + if kip != 0 { + return u64(kip.ki_rssize * page_size) + } + } + return 0 +} diff --git a/vlib/runtime/used_memory_test.v b/vlib/runtime/used_memory_test.v index 24580fdf40..20135fc912 100644 --- a/vlib/runtime/used_memory_test.v +++ b/vlib/runtime/used_memory_test.v @@ -4,18 +4,21 @@ 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) } - + mut mem1 := unsafe { malloc(8 * 1024 * 1024) } + unsafe { vmemset(mem1, 1, 8 * 1024 * 1024) } used2 := runtime.used_memory()! println('used memory 2 : ${used2}') - mut mem2 := unsafe { malloc(8192 * 1024) } - unsafe { vmemset(mem2, 1, 8192 * 1024) } - + mut mem2 := unsafe { malloc(64 * 1024 * 1024) } + unsafe { vmemset(mem2, 1, 64 * 1024 * 1024) } used3 := runtime.used_memory()! println('used memory 3 : ${used3}') + assert used1 > 0 - assert used2 > used1 + assert used2 >= used1 assert used3 > used2 + unsafe { + println(*&u8(mem1 + 1024)) + println(*&u8(mem2 + 1024)) + } }