| 1 | module runtime |
| 2 | |
| 3 | #include <mach/mach.h> |
| 4 | #include <mach/task.h> |
| 5 | |
| 6 | @[typedef] |
| 7 | pub struct C.vm_size_t { |
| 8 | } |
| 9 | |
| 10 | @[typedef] |
| 11 | pub struct C.vm_statistics64_data_t { |
| 12 | free_count u32 |
| 13 | purgeable_count u32 |
| 14 | speculative_count u32 |
| 15 | external_page_count u32 |
| 16 | } |
| 17 | |
| 18 | @[typedef] |
| 19 | pub struct C.host_t {} |
| 20 | |
| 21 | @[typedef] |
| 22 | pub struct C.task_t {} |
| 23 | |
| 24 | fn C.mach_host_self() C.host_t |
| 25 | fn C.mach_task_self() C.task_t |
| 26 | fn C.mach_port_deallocate(task C.task_t, host C.host_t) i32 |
| 27 | fn C.host_page_size(host C.host_t, out_page_size &C.vm_size_t) i32 |
| 28 | fn C.host_statistics64(host C.host_t, flavor i32, host_info_out &int, host_info_outCnt &u32) i32 |
| 29 | |
| 30 | fn free_memory_impl() !usize { |
| 31 | $if macos { |
| 32 | mut hs := C.vm_statistics64_data_t{} |
| 33 | mut vmsz := u32(C.HOST_VM_INFO64_COUNT) |
| 34 | mut hps := u32(0) |
| 35 | mut host := C.mach_host_self() |
| 36 | defer { |
| 37 | // Critical: Release send right for host port |
| 38 | // -------------------------------------------------- |
| 39 | // Mach ports are system resources. Calling mach_host_self() |
| 40 | // increments the port's reference count. We must manually release |
| 41 | // to prevent resource leaks (port exhaustion can cause kernel failures). |
| 42 | // mach_port_deallocate decrements the reference count, allowing |
| 43 | // system resource reclamation when count reaches zero. |
| 44 | // Parameters: |
| 45 | // C.mach_task_self() - Port for current task |
| 46 | // host - Host port to release |
| 47 | // Return value ignored (_) since we only care about resource cleanup |
| 48 | _ := C.mach_port_deallocate(C.mach_task_self(), host) |
| 49 | } |
| 50 | unsafe { |
| 51 | retval_1 := C.host_statistics64(host, C.HOST_VM_INFO64, &int(&hs), &vmsz) |
| 52 | if retval_1 != C.KERN_SUCCESS { |
| 53 | return error('free_memory: `C.host_statistics64()` return = ${retval_1}') |
| 54 | } |
| 55 | retval_2 := C.host_page_size(host, &C.vm_size_t(&hps)) |
| 56 | if retval_2 != C.KERN_SUCCESS { |
| 57 | return error('free_memory: `C.host_page_size()` return = ${retval_2}') |
| 58 | } |
| 59 | } |
| 60 | return usize(u64(hs.free_count) * u64(hps)) |
| 61 | } |
| 62 | return error('free_memory: not implemented') |
| 63 | } |
| 64 | |