runtime: add used_memory() implementation for FreeBSD (#24909)

This commit is contained in:
Kim Shrier 2025-07-17 01:14:01 -06:00 committed by GitHub
parent 54c6daab54
commit c3dfe62d7b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 73 additions and 8 deletions

View File

@ -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')

View File

@ -0,0 +1,62 @@
module runtime
import os
$if tinyc {
#include <sys/resource.h>
}
struct C.rusage {
ru_maxrss int
ru_idrss int
}
fn C.getrusage(who int, usage &C.rusage) int
$if !tinyc {
#flag -lprocstat
#include <sys/user.h>
#include <libprocstat.h>
}
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
}

View File

@ -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))
}
}