core/failing
Shared: available on every enabled target.
Deterministic allocation-failure injection over any allocator, with cumulative counters.
The budget counts delegated attempts, including attempts the inner provider refuses. permit replaces that budget without resetting evidence. Free calls delegate to the parent; in-place growth is refused so allocation-failure tests remain predictable.
Items
- counted type
- attempts function
- delegated function
- frees function
- injected_failures function
- inner_failures function
- live function
- new function
- permit function
- remaining function
- successes function
Executable example
This complete program is maintained in the repository runtime tests. View source.
import core/mem import core/failing exercise: () -> (ok: bool) ! mem.out_of_memory = ok = false mut backing: [32]u8 = zeroed mut inner := mem.arena_over_unchecked(addr backing[0], 32) mut state := failing.new(addr inner, usize(1)) address := try mem.allocate(state, usize(4), usize(1)) address.val = 42 return when address.val <> 42 _ = mem.allocate(state, usize(4), usize(1)) else (problem) _ = problem ok = failing.successes(state) == 1 and failing.injected_failures(state) == 1 mem.free(state, address, usize(4)) return end end exercise public main: () -> (code: i32) = code = 1 ok := exercise() else false if ok then code = 42 end if end main
counted type
public counted: type (inner_provider: type) = struct
inner: ptr mut inner_provider
remaining: usize
attempts: usize
delegated: usize
successes: usize
injected_failures: usize
inner_failures: usize
frees: usize
live: usize
end countedAllocator wrapper with deterministic failure injection and cumulative counters. Borrows its inner provider, delegates permitted allocations and frees, and refuses in-place growth.
attempts function
public attempts: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return all allocation attempts, including injected and inner failures.
delegated function
public delegated: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return allocation attempts passed through to the inner provider.
frees function
public frees: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return the number of delegated free calls.
injected_failures function
public injected_failures: (inner_provider: type,
state: counted(inner_provider))
-> (count: usize)Return attempts rejected by the wrapper before calling the inner provider.
inner_failures function
public inner_failures: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return allocation failures reported by the inner provider.
live function
public live: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return successful allocations minus free calls, bounded below by zero. Exact under the allocator contract; malformed or duplicate frees are not validated here.
new function
public new: (inner_provider: type is mem.allocator,
inner: ptr mut inner_provider,
allowed_attempts: usize)
-> (state: counted(inner_provider) from inner)Wrap an allocator with an allocation-attempt budget. Inner failures consume the budget too; injected failures never call the inner provider.
allowed_attempts is the number of future allocation calls allowed to reach inner.alloc. An inner failure consumes one such attempt. Injected failures increment attempts/injected_failures only and never call inner.
permit function
public permit: (inner_provider: type,
inout state: counted(inner_provider),
allowed_attempts: usize) -> noneReplace the future delegation budget without resetting accumulated counters.
Replace only the future delegation budget. Evidence counters accumulate across retries so the failed and successful calls remain distinguishable.
remaining function
public remaining: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return how many allocation attempts may still reach the inner provider.
successes function
public successes: (inner_provider: type,
state: counted(inner_provider)) -> (count: usize)Return the number of successful delegated allocations.