feature. See also
. The project being documented here (as the example) is the Zig library itself.
ArenaAllocator.FuzzAllocator
const FuzzAllocator = struct
File
Code
const FuzzAllocator = struct {
fba: std.heap.FixedBufferAllocator,
spurious_failures: [256]u8,
index: u8,
fn init(buffer: []u8) FuzzAllocator {
@disableInstrumentation();
return .{
.fba = .init(buffer),
.spurious_failures = undefined,
.index = 0,
};
}
fn prepareFailures(fa: *FuzzAllocator, smith: *std.testing.Smith) void {
@disableInstrumentation();
const bool_weights: []const std.testing.Smith.Weight = &.{
.value(u8, 0, 10),
.value(u8, 1, 1),
};
smith.bytesWeighted(&fa.spurious_failures, bool_weights);
fa.index = 0;
}
fn reset(fa: *FuzzAllocator) void {
@disableInstrumentation();
fa.fba.reset();
}
fn allocator(fa: *FuzzAllocator) Allocator {
@disableInstrumentation();
return .{
.ptr = fa,
.vtable = &.{
.alloc = FuzzAllocator.alloc,
.resize = FuzzAllocator.resize,
.remap = FuzzAllocator.remap,
.free = FuzzAllocator.free,
},
};
}
fn alloc(ctx: *anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8 {
@disableInstrumentation();
const fa: *FuzzAllocator = @ptrCast(@alignCast(ctx));
_ = ret_addr;
const index = @atomicRmw(u8, &fa.index, .Add, 1, .monotonic);
if (fa.spurious_failures[index] != 0) return null;
return fa.fba.threadSafeAllocator().rawAlloc(len, alignment, @returnAddress());
}
fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool {
@disableInstrumentation();
const fa: *FuzzAllocator = @ptrCast(@alignCast(ctx));
_ = ret_addr;
const index = @atomicRmw(u8, &fa.index, .Add, 1, .monotonic);
if (fa.spurious_failures[index] != 0) return false;
return fa.fba.threadSafeAllocator().rawResize(memory, alignment, new_len, @returnAddress());
}
fn remap(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
@disableInstrumentation();
const fa: *FuzzAllocator = @ptrCast(@alignCast(ctx));
_ = ret_addr;
const index = @atomicRmw(u8, &fa.index, .Add, 1, .monotonic);
if (fa.spurious_failures[index] != 0) return null;
return fa.fba.threadSafeAllocator().rawRemap(memory, alignment, new_len, @returnAddress());
}
fn free(ctx: *anyopaque, memory: []u8, alignment: Alignment, ret_addr: usize) void {
@disableInstrumentation();
const fa: *FuzzAllocator = @ptrCast(@alignCast(ctx));
_ = ret_addr;
return fa.fba.threadSafeAllocator().rawFree(memory, alignment, @returnAddress());
}
}