aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/mem.zig14
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;