feature. See also
. The project being documented here (as the example) is the Zig library itself.
ArenaAllocator.resize
fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool
File
Code
fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool {
const arena: *ArenaAllocator = @ptrCast(@alignCast(ctx));
_ = alignment;
_ = ret_addr;
assert(memory.len > 0);
assert(new_len > 0);
const node = arena.loadFirstNode().?;
const buf_ptr = @as([*]u8, @ptrCast(node)) + @sizeOf(Node);
const cur_end_index = @atomicLoad(usize, &node.end_index, .monotonic);
if (buf_ptr + cur_end_index != memory.ptr + memory.len) {
// but it's fine if they want to make it smaller.
return new_len <= memory.len;
}
if (new_len <= memory.len) {
const new_end_index = cur_end_index - (memory.len - new_len);
assert(buf_ptr + new_end_index == memory.ptr + new_len);
_ = @cmpxchgStrong(
usize,
&node.end_index,
cur_end_index,
new_end_index,
.release,
.monotonic,
);
return true;
}
// The allocation we're trying to resize *could* belong to a different node!
if (node.loadBuf().len -| cur_end_index >= new_len - memory.len) {
const new_end_index = cur_end_index + (new_len - memory.len);
assert(buf_ptr + new_end_index == memory.ptr + new_len);
return null == @cmpxchgStrong(
usize,
&node.end_index,
cur_end_index,
new_end_index,
.acquire,
.monotonic,
);
}
return false;
}