@@ -39,22 +39,24 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
39
39
return struct {
40
40
const Pool = @This ();
41
41
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.
44
44
pub const item_size = @max (@sizeOf (Node ), @sizeOf (Item ));
45
45
46
46
// This needs to be kept in sync with Node.
47
47
const node_alignment : Alignment = .of (* anyopaque );
48
48
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.
51
51
pub const item_alignment : Alignment = node_alignment .max (pool_options .alignment orelse .of (Item ));
52
52
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 ;
58
60
59
61
arena : std.heap.ArenaAllocator ,
60
62
free_list : ? NodePtr = null ,
@@ -84,13 +86,11 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
84
86
/// This allows up to `size` active allocations before an
85
87
/// `OutOfMemory` error might happen when calling `create()`.
86
88
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 ;
94
94
pool .free_list = free_node ;
95
95
}
96
96
}
@@ -119,15 +119,15 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
119
119
120
120
/// Creates a new item and adds it to the memory pool.
121
121
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 : {
123
123
pool .free_list = item .next ;
124
124
break :blk item ;
125
125
} else if (pool_options .growable )
126
- @as ( NodePtr , @ ptrCast (try pool .allocNew () ))
126
+ @ptrCast (try pool .allocNew (1 ))
127
127
else
128
128
return error .OutOfMemory ;
129
129
130
- const ptr = @as ( ItemPtr , @ ptrCast (node ) );
130
+ const ptr : ItemPtr = @ptrCast (node_ptr );
131
131
ptr .* = undefined ;
132
132
return ptr ;
133
133
}
@@ -136,17 +136,14 @@ pub fn MemoryPoolExtra(comptime Item: type, comptime pool_options: Options) type
136
136
/// Only pass items to `ptr` that were previously created with `create()` of the same memory pool!
137
137
pub fn destroy (pool : * Pool , ptr : ItemPtr ) void {
138
138
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 ;
145
142
}
146
143
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 ;
150
147
}
151
148
};
152
149
}
0 commit comments