Skip to content

Commit c3dfe62

Browse files
authored
runtime: add used_memory() implementation for FreeBSD (#24909)
1 parent 54c6daa commit c3dfe62

3 files changed

Lines changed: 73 additions & 8 deletions

File tree

‎vlib/runtime/used_memory_default.c.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module runtime
22

33
// used_memory retrieves the current physical memory usage of the process.
4-
// Note: implementation available only on macOS, Linux and Windows. Otherwise,
4+
// Note: implementation available only on FreeBSD, macOS, Linux and Windows. Otherwise,
55
// returns 'used_memory: not implemented'.
66
pub fn used_memory() !u64 {
77
return error('used_memory: not implemented')
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
module runtime
2+
3+
import os
4+
5+
$if tinyc {
6+
#include <sys/resource.h>
7+
}
8+
struct C.rusage {
9+
ru_maxrss int
10+
ru_idrss int
11+
}
12+
13+
fn C.getrusage(who int, usage &C.rusage) int
14+
15+
$if !tinyc {
16+
#flag -lprocstat
17+
18+
#include <sys/user.h>
19+
#include <libprocstat.h>
20+
}
21+
struct C.procstat {}
22+
23+
struct C.kinfo_proc {
24+
ki_rssize u64
25+
}
26+
27+
fn C.procstat_open_sysctl() &C.procstat
28+
fn C.procstat_close(&C.procstat)
29+
fn C.procstat_getprocs(&C.procstat, int, int, &u32) &C.kinfo_proc
30+
31+
// used_memory retrieves the current physical memory usage of the process.
32+
pub fn used_memory() !u64 {
33+
page_size := usize(C.sysconf(C._SC_PAGESIZE))
34+
c_errno_1 := C.errno
35+
if page_size == usize(-1) {
36+
return error('used_memory: C.sysconf() return error code = ${c_errno_1}')
37+
}
38+
$if tinyc {
39+
mut usage := C.rusage{}
40+
x := C.getrusage(0, &usage)
41+
if x == -1 {
42+
c_errno_2 := C.errno
43+
return error('used_memory: C.getrusage() return error code = ${c_errno_2}')
44+
}
45+
return u64(int_max(1, usage.ru_maxrss)) * 1024
46+
} $else {
47+
mut proc_status := C.procstat_open_sysctl()
48+
defer {
49+
C.procstat_close(proc_status)
50+
}
51+
52+
mut count := u32(0)
53+
54+
kip := C.procstat_getprocs(proc_status, C.KERN_PROC_PID | C.KERN_PROC_INC_THREAD,
55+
os.getpid(), &count)
56+
57+
if kip != 0 {
58+
return u64(kip.ki_rssize * page_size)
59+
}
60+
}
61+
return 0
62+
}

‎vlib/runtime/used_memory_test.v‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ fn test_used_memory() {
44
used1 := runtime.used_memory()!
55
println('used memory 1 : ${used1}')
66

7-
mut mem1 := unsafe { malloc(4096 * 1024) }
8-
unsafe { vmemset(mem1, 1, 4096 * 1024) }
9-
7+
mut mem1 := unsafe { malloc(8 * 1024 * 1024) }
8+
unsafe { vmemset(mem1, 1, 8 * 1024 * 1024) }
109
used2 := runtime.used_memory()!
1110
println('used memory 2 : ${used2}')
1211

13-
mut mem2 := unsafe { malloc(8192 * 1024) }
14-
unsafe { vmemset(mem2, 1, 8192 * 1024) }
15-
12+
mut mem2 := unsafe { malloc(64 * 1024 * 1024) }
13+
unsafe { vmemset(mem2, 1, 64 * 1024 * 1024) }
1614
used3 := runtime.used_memory()!
1715
println('used memory 3 : ${used3}')
16+
1817
assert used1 > 0
19-
assert used2 > used1
18+
assert used2 >= used1
2019
assert used3 > used2
20+
unsafe {
21+
println(*&u8(mem1 + 1024))
22+
println(*&u8(mem2 + 1024))
23+
}
2124
}

0 commit comments

Comments
 (0)