rokdocs
v0.1

1.4. raw allocation - alloc / dealloc / realloc

The rok::bare::alloc module provides an API for allocating and freeing memory directly in a region outside the GC's control. Ordinary rok code is managed by the GC, but this module is used where the GC is not a good fit: handing memory to the C side across an FFI boundary, large buffers, mmap and the like.

1.4.1. API

struct Layout {
    size: usize;
    align: usize;
}

impl Layout {
    fn new<T>() -> Layout;                     // size_of<T>(), align_of<T>()
    fn array<T>(n: usize) throws (LayoutError) -> Layout;
    fn from_size_align(size: usize, align: usize) throws (LayoutError) -> Layout;
}

unsafe fn alloc(layout: Layout) -> CPtr<u8>;
unsafe fn alloc_zeroed(layout: Layout) -> CPtr<u8>;
unsafe fn dealloc(ptr: Ptr<u8>, layout: Layout);
unsafe fn realloc(ptr: Ptr<u8>, old_layout: Layout, new_size: usize) -> CPtr<u8>;

// convenience functions - typed
unsafe fn alloc_one<T>() -> CPtr<T>;
unsafe fn alloc_array<T>(n: usize) -> CPtr<T>;
unsafe fn dealloc_one<T>(ptr: Ptr<T>);
unsafe fn dealloc_array<T>(ptr: Ptr<T>, n: usize);

If alloc fails it returns CPtr::null(); it does not abort, so the caller must check and handle the result.

1.4.2. Example

let layout = try Layout::array::<u32>(1000);
let p: CPtr<u8> = unsafe { rok::bare::alloc::alloc(layout) };

match p.as_ptr() {
    raw: Ptr<u8> => {
        let typed: Ptr<u32> = rok::bare::ptr_cast::<u32>(raw);
        // use
        unsafe {
            for i in 0u32..1000u32 { typed.add(i as usize).write(i); }
        }
        unsafe { rok::bare::alloc::dealloc(raw, layout) };
    }
    none => panic("alloc failed"),
}

With a using block, cleanup takes RAII form.

using buf = try rok::bare::alloc::Allocation::<u32>::new(1000) {
    // buf.as_ptr() is usable
}     // ← automatic dealloc

Here Allocation<T> is the RAII wrapper included in this module.

1.4.3. Relationship with the GC

RegionAllocation / deallocationGC-managed?
Ordinary objects (List<i32>)GC TLAB bump✓
rok::bare::alloc::allocsystem malloc✗ (manual)
FFI mallocC malloc✗
Large object (≥8KB)LOS - non-moving mark-sweep✓ (but non-moving)

If a GC-managed raw buffer is needed, use rok::core::collections::raw::GcBuf<T> (2.9.12) instead of this module.

Regions outside the GC are not traced by it, so cleanup is the user's responsibility. Since objects there do not move, however, a Ptr<T> stays valid without a separate pin guard.

1.4.4. Runtime linkage

The body of rok::bare::alloc::alloc lowers to a wrapper the rok runtime provides over system malloc, ultimately calling libc::malloc / libc::free / libc::realloc.

Edit this page on GitHub