Skip to content

Commit a56f564

Browse files
committed
Allocate only once for preheating.
More uniform comments.
1 parent 12ed0ff commit a56f564

File tree

1 file changed

+25
-28
lines changed

1 file changed

+25
-28
lines changed

lib/std/heap/memory_pool.zig

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,24 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
3939
return struct {
4040
const Pool = @This();
4141

42-
/// Size of the memory pool items. This is not necessarily the same
43-
/// as `@sizeOf(Item)` as the pool also uses the items for internal means.
42+
/// Size of the memory pool items. This may be larger than `@sizeOf(Item)`
43+
/// as the pool also uses the items for internal means.
4444
pub const item_size = @max(@sizeOf(Node), @sizeOf(Item));
4545

4646
// This needs to be kept in sync with Node.
4747
const node_alignment: Alignment = .of(*anyopaque);
4848

49-
/// Alignment of the memory pool items. This is not necessarily the same
50-
/// as `@alignOf(Item)` as the pool also uses the items for internal means.
49+
/// Alignment of the memory pool items. This may be larger than `@alignOf(Item)`
50+
/// as the pool also uses the items for internal means.
5151
pub const item_alignment: Alignment = node_alignment.max(pool_options.alignment orelse .of(Item));
5252

53-
const Node = struct {
54-
next: ?*align(item_alignment.toByteUnits()) @This(),
55-
};
56-
const NodePtr = *align(item_alignment.toByteUnits()) Node;
57-
const ItemPtr = *align(item_alignment.toByteUnits()) Item;
53+
const Node = struct { next: ?*align(unit_al_bytes) @This() };
54+
const Byte = std.meta.Int(.unsigned, std.mem.byte_size_in_bits);
55+
const Unit = [item_alignment.forward(item_size)]Byte;
56+
const unit_al_bytes = item_alignment.toByteUnits();
57+
58+
const ItemPtr = *align(unit_al_bytes) Item;
59+
const NodePtr = *align(unit_al_bytes) Node;
5860

5961
arena: std.heap.ArenaAllocator,
6062
free_list: ?NodePtr = null,
@@ -84,13 +86,11 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
8486
/// This allows up to `size` active allocations before an
8587
/// `OutOfMemory` error might happen when calling `create()`.
8688
pub fn preheat(pool: *Pool, size: usize) MemoryPoolError!void {
87-
var i: usize = 0;
88-
while (i < size) : (i += 1) {
89-
const raw_mem = try pool.allocNew();
90-
const free_node = @as(NodePtr, @ptrCast(raw_mem));
91-
free_node.* = Node{
92-
.next = pool.free_list,
93-
};
89+
const raw_mem = try pool.allocNew(size);
90+
const uni_slc = raw_mem[0..size];
91+
for (uni_slc) |*unit| {
92+
const free_node: NodePtr = @ptrCast(unit);
93+
free_node.next = pool.free_list;
9494
pool.free_list = free_node;
9595
}
9696
}
@@ -119,15 +119,15 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
119119

120120
/// Creates a new item and adds it to the memory pool.
121121
pub fn create(pool: *Pool) !ItemPtr {
122-
const node = if (pool.free_list) |item| blk: {
122+
const node_ptr: NodePtr = if (pool.free_list) |item| blk: {
123123
pool.free_list = item.next;
124124
break :blk item;
125125
} else if (pool_options.growable)
126-
@as(NodePtr, @ptrCast(try pool.allocNew()))
126+
@ptrCast(try pool.allocNew(1))
127127
else
128128
return error.OutOfMemory;
129129

130-
const ptr = @as(ItemPtr, @ptrCast(node));
130+
const ptr: ItemPtr = @ptrCast(node_ptr);
131131
ptr.* = undefined;
132132
return ptr;
133133
}
@@ -136,17 +136,14 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
136136
/// Only pass items to `ptr` that were previously created with `create()` of the same memory pool!
137137
pub fn destroy(pool: *Pool, ptr: ItemPtr) void {
138138
ptr.* = undefined;
139-
140-
const node = @as(NodePtr, @ptrCast(ptr));
141-
node.* = Node{
142-
.next = pool.free_list,
143-
};
144-
pool.free_list = node;
139+
const node_ptr: NodePtr = @ptrCast(ptr);
140+
node_ptr.next = pool.free_list;
141+
pool.free_list = node_ptr;
145142
}
146143

147-
fn allocNew(pool: *Pool) MemoryPoolError!*align(item_alignment.toByteUnits()) [item_size]u8 {
148-
const mem = try pool.arena.allocator().alignedAlloc(u8, item_alignment, item_size);
149-
return mem[0..item_size]; // coerce slice to array pointer
144+
fn allocNew(pool: *Pool, n: usize) MemoryPoolError![*]align(unit_al_bytes) Unit {
145+
const mem = try pool.arena.allocator().alignedAlloc(Unit, item_alignment, n);
146+
return mem.ptr;
150147
}
151148
};
152149
}

0 commit comments

Comments
 (0)