Landin library reference source

core/pool

Shared: available on every enabled target.

A reclaiming allocator over fixed-size slots and caller-supplied bookkeeping.

The pool allocates no backing storage of its own. It reuses the lowest free slot and rejects malformed frees without reclaiming a slot. A zero-byte allocation still occupies one slot. Keep both payload backing and metadata alive while allocations exist.

Items

Executable example

This complete program is maintained in the repository runtime tests. View source.

import core/mem
import core/pool

exercise: () -> (ok: bool) ! mem.out_of_memory =
    ok = false
    mut backing: [64]u8 = zeroed
    mut slots: [1]pool.slot = zeroed
    mut state := try pool.over(addr backing[0], 64, 16, 1, 1, slots[0..<1])
    address := try mem.allocate(state, usize(16), usize(1))
    address.val = 42
    return when address.val <> 42 or pool.live(state) <> 1
    _ = mem.allocate(state, usize(1), usize(1)) else (problem)
        _ = problem
        mem.free(state, address, usize(16))
        ok = pool.live(state) == 0 and pool.free_count(state) == 1
        return
    end
end exercise

public main: () -> (code: i32) =
    code = 1
    ok := exercise() else false
    if ok then
        code = 42
    end if
end main

provider type

public provider: type = fixed_pool

core/pool/pool.ldn:34

Reclaiming allocator over uniform slots in caller storage. Reuses the lowest free index, never grows in place, and uses no fallback allocator. Even a zero-byte allocation occupies a slot.

slot type

public slot: type = struct
    size: usize
    free_index: usize
end slot

core/pool/pool.ldn:10

Caller-owned bookkeeping record for one pool slot. Supply an initialized slice to over; the provider maintains its fields after construction.

allocation_count function

public allocation_count: (state: provider) -> (count: usize)

core/pool/pool.ldn:282

Return the number of successful allocations, including zero-byte allocations.

bookkeeping_capacity function

public bookkeeping_capacity: (state: provider) -> (count: usize)

core/pool/pool.ldn:270

Return the length of the supplied metadata slice, which may exceed the configured slot count.

capacity function

public capacity: (state: provider) -> (count: usize)

core/pool/pool.ldn:264

Return the configured number of allocatable slots.

free_count function

public free_count: (state: provider) -> (count: usize)

core/pool/pool.ldn:287

Return the number of successful slot reclamations.

live function

public live: (state: provider) -> (count: usize)

core/pool/pool.ldn:276

Return the number of currently allocated slots.

over function

public over: (base: ptr mut u8, extent: usize, slot_size: usize,
              slot_count: usize, slot_alignment: usize,
              bookkeeping: []mut slot)
             -> (state: provider from base, bookkeeping)
             ! mem.out_of_memory

core/pool/pool.ldn:91

Construct a pool over caller backing and bookkeeping. Validates positive slot size, alignment, extent and record capacity before publishing the provider. Keep both backing ranges alive until all allocations end.

slot_size is positive. The initialized bookkeeping slice is supplied by the caller, its length is the finite bookkeeping capacity, and slot_count may be zero but may not exceed it. The maximum usize marks a free slot, so a positive pool cannot use that slot size. A positive pool aligns its first slot from the absolute backing address, includes that padding in extent accounting, and proves every later slot and its complete payload fit both the backing extent and target address space before publishing the provider.

rejected_free_count function

public rejected_free_count: (state: provider) -> (count: usize)

core/pool/pool.ldn:293

Return frees rejected for an invalid address, extent or already-free slot. A rejected free does not reclaim a slot.