metrale_gpu_runtime/
host_heap.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-25: The heap allocation behind the default `GpuBackend::alloc_host_pinned`
4//! and `free_host_pinned`. The mock allocates the same zeroed `(bytes, 64)` layout
5//! itself, to count calls, and frees through the default.
6//!
7//! Owner: gpu-runtime.
8//! Invariants:
9//! - A block is zeroed, 64-byte aligned, and freed with the same `(bytes, 64)`
10//!   layout it was allocated with, so `free` must get the allocated size.
11
12use anyhow::Result;
13
14pub fn alloc_zeroed(bytes: usize) -> Result<*mut u8> {
15    let layout = std::alloc::Layout::from_size_align(bytes, 64)
16        .map_err(|e| anyhow::anyhow!("invalid layout: {e}"))?;
17    let ptr = unsafe { std::alloc::alloc_zeroed(layout) };
18    if ptr.is_null() {
19        anyhow::bail!("host alloc failed: {bytes} bytes");
20    }
21    Ok(ptr)
22}
23
24#[allow(clippy::not_unsafe_ptr_arg_deref)]
25pub fn free(ptr: *mut u8, bytes: usize) -> Result<()> {
26    if !ptr.is_null() {
27        let layout = std::alloc::Layout::from_size_align(bytes, 64)
28            .map_err(|e| anyhow::anyhow!("invalid layout: {e}"))?;
29        unsafe { std::alloc::dealloc(ptr, layout) };
30    }
31    Ok(())
32}