Skip to content

Instantly share code, notes, and snippets.

@rlapz
Last active January 23, 2024 13:55
Show Gist options
  • Save rlapz/1d8dbf93a1a1e33a140158bd204d2139 to your computer and use it in GitHub Desktop.
Save rlapz/1d8dbf93a1a1e33a140158bd204d2139 to your computer and use it in GitHub Desktop.
A simple memory pool.
const std = @import("std");
const mem = std.mem;
const debug = std.debug;
const assert = debug.assert;
const dprint = debug.print;
pub fn MemPool(comptime T: type) type {
return struct {
allocator: mem.Allocator,
head: ?*Node,
const Self = @This();
const Node = struct {
prev: ?*Node,
data: T,
};
pub fn init(allocator: mem.Allocator, size: usize) !Self {
var ret: Self = .{
.allocator = allocator,
.head = null,
};
errdefer ret.deinit();
var i: usize = 0;
while (i < size) : (i += 1) {
var new_node = try allocator.create(Node);
new_node.prev = ret.head;
ret.head = new_node;
}
return ret;
}
pub fn deinit(self: *Self) void {
var head = self.head;
while (head != null) {
const prev = head.?.prev;
self.allocator.destroy(head.?);
head = prev;
}
self.head = null;
}
pub fn create(self: *Self) !*T {
var head = self.head;
if (head != null)
self.head = head.?.prev
else
head = try self.allocator.create(Node);
return &head.?.data;
}
pub fn reserve(self: *Self, item_ptr: *T) void {
const node = @fieldParentPtr(Node, "data", item_ptr);
node.prev = self.head;
self.head = node;
}
pub fn destroy(self: *Self, item_ptr: *T) void {
item_ptr.* = undefined;
const node = @fieldParentPtr(Node, "data", item_ptr);
self.allocator.destroy(node);
}
};
}
test {
const MP = MemPool(u32);
const len = 100;
var arr: [len]*u32 = undefined;
var mp = try MP.init(std.testing.allocator, 0);
defer mp.deinit();
var i: u32 = 0;
while (i < len) : (i += 1) {
const num = try mp.create();
num.* = i;
arr[i] = num;
}
i = 0;
while (i < len) : (i += 1)
dprint("{}\n", .{arr[i].*});
i = 0;
while (i < len) : (i += 1) {
dprint("{*}: {}\n", .{ arr[i], arr[i].* });
mp.reserve(arr[i]);
}
arr[10] = try mp.create();
arr[10].* = 123;
defer mp.reserve(arr[10]);
i = 0;
while (i < len) : (i += 1)
dprint("{*}: {}\n", .{ arr[i], arr[i].* });
const x = try mp.create();
mp.destroy(x);
const y = try mp.create();
mp.destroy(y);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment