diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/mem.zig | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/lib/mem.zig b/src/lib/mem.zig index a9addf6..6f6ef5f 100644 --- a/src/lib/mem.zig +++ b/src/lib/mem.zig @@ -79,6 +79,7 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type { var chunk = self.head orelse return null; const bound = @intFromPtr(chunk) + (self.pages * paging.page_size); + var predecessor: ?*align(1) Chunk = null; while (@intFromPtr(chunk) < bound) : (chunk = chunk.next()) { const adjust_off = std.mem.alignPointerOffset(chunk.data().ptr, ptr_align) orelse return null; const aligned_len = len + adjust_off; @@ -87,10 +88,16 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type { if (!@bitCast(chunk.flags.active) and chunk.len >= aligned_len) { const remaining = chunk.len - aligned_len; + if (predecessor) |*pred| { + pred.*.len += adjust_off; + } else if (adjust_off != 0) return null; + + chunk = @ptrFromInt(@intFromPtr(chunk) + adjust_off); + chunk.clear(); chunk.take(); if (remaining > @sizeOf(Chunk)) { - chunk.len = aligned_len; + chunk.len = len; const new_successor = chunk.next(); @@ -98,8 +105,10 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type { new_successor.len = remaining - @sizeOf(Chunk); } - return @ptrCast(std.mem.alignPointer(chunk.data().ptr, ptr_align)); + return chunk.data().ptr; } + + predecessor = chunk; } return null; @@ -117,7 +126,6 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type { const head = self.head orelse return false; const bound = @intFromPtr(head) + (self.pages * paging.page_size); - // fixme: Doesn't account for alignment between header and data. const chunk = @as(*align(1) Chunk, @ptrCast(buf.ptr - @sizeOf(Chunk))); const adjust_off = std.mem.alignPointerOffset(buf.ptr, ptr_align) orelse return false; |