Skip to content

Commit

Permalink
Fix build failure in sbrk allocator, caused by ziglang#20511
Browse files Browse the repository at this point in the history
  • Loading branch information
schtvn committed Feb 17, 2025
1 parent d7b93c7 commit 0f15847
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
1 change: 1 addition & 0 deletions lib/std/heap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ test {
_ = GeneralPurposeAllocator;
_ = FixedBufferAllocator;
_ = ThreadSafeAllocator;
_ = SbrkAllocator;
if (builtin.target.isWasm()) {
_ = WasmAllocator;
}
Expand Down
34 changes: 26 additions & 8 deletions lib/std/heap/sbrk_allocator.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
pub const vtable: Allocator.VTable = .{
.alloc = alloc,
.resize = resize,
.remap = remap,
.free = free,
};

Expand All @@ -19,7 +20,6 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
const max_usize = math.maxInt(usize);
const ushift = math.Log2Int(usize);
const bigpage_size = 64 * 1024;
const pages_per_bigpage = bigpage_size / heap.pageSize();
const bigpage_count = max_usize / bigpage_size;

/// Because of storing free list pointers, the minimum size class is 3.
Expand All @@ -39,13 +39,13 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {

// TODO don't do the naive locking strategy
var lock: std.Thread.Mutex = .{};
fn alloc(ctx: *anyopaque, len: usize, log2_align: u8, return_address: usize) ?[*]u8 {
fn alloc(ctx: *anyopaque, len: usize, log2_align: mem.Alignment, return_address: usize) ?[*]u8 {
_ = ctx;
_ = return_address;
lock.lock();
defer lock.unlock();
// Make room for the freelist next pointer.
const alignment = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_align));
const alignment = log2_align.toByteUnits();
const actual_len = @max(len +| @sizeOf(usize), alignment);
const slot_size = math.ceilPowerOfTwo(usize, actual_len) catch return null;
const class = math.log2(slot_size) - min_class;
Expand Down Expand Up @@ -82,7 +82,7 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
fn resize(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
log2_buf_align: mem.Alignment,
new_len: usize,
return_address: usize,
) bool {
Expand All @@ -92,7 +92,7 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
defer lock.unlock();
// We don't want to move anything from one size class to another, but we
// can recover bytes in between powers of two.
const buf_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_buf_align));
const buf_align = log2_buf_align.toByteUnits();
const old_actual_len = @max(buf.len + @sizeOf(usize), buf_align);
const new_actual_len = @max(new_len +| @sizeOf(usize), buf_align);
const old_small_slot_size = math.ceilPowerOfTwoAssert(usize, old_actual_len);
Expand All @@ -109,17 +109,27 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
}
}

fn remap(
context: *anyopaque,
memory: []u8,
alignment: mem.Alignment,
new_len: usize,
return_address: usize,
) ?[*]u8 {
return if (resize(context, memory, alignment, new_len, return_address)) memory.ptr else null;
}

fn free(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
log2_buf_align: mem.Alignment,
return_address: usize,
) void {
_ = ctx;
_ = return_address;
lock.lock();
defer lock.unlock();
const buf_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_buf_align));
const buf_align = log2_buf_align.toByteUnits();
const actual_len = @max(buf.len + @sizeOf(usize), buf_align);
const slot_size = math.ceilPowerOfTwoAssert(usize, actual_len);
const class = math.log2(slot_size) - min_class;
Expand Down Expand Up @@ -154,7 +164,15 @@ pub fn SbrkAllocator(comptime sbrk: *const fn (n: usize) usize) type {
big_frees[class] = node.*;
return top_free_ptr;
}
return sbrk(pow2_pages * pages_per_bigpage * heap.pageSize());
return sbrk(pow2_pages * bigpage_size * heap.pageSize());
}
};
}

test SbrkAllocator {
_ = SbrkAllocator(struct {
fn sbrk(_: usize) usize {
return 0;
}
}.sbrk);
}

0 comments on commit 0f15847

Please sign in to comment.