aboutsummaryrefslogtreecommitdiff
path: root/mirai/memory/kalloc
diff options
context:
space:
mode:
Diffstat (limited to 'mirai/memory/kalloc')
-rw-r--r--mirai/memory/kalloc/kalloc.zig75
1 files changed, 75 insertions, 0 deletions
diff --git a/mirai/memory/kalloc/kalloc.zig b/mirai/memory/kalloc/kalloc.zig
new file mode 100644
index 0000000..49765b6
--- /dev/null
+++ b/mirai/memory/kalloc/kalloc.zig
@@ -0,0 +1,75 @@
+//! Kernel Allocator
+
+const types = @import("../zone/types/types.zig");
+const Zone = types.Zone;
+
+const create_mod = @import("../zone/create/create.zig");
+const alloc_mod = @import("../zone/alloc/alloc.zig");
+const bootstrap = @import("../zone/bootstrap/bootstrap.zig");
+
+pub const sizes = [_]usize{ 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
+const zone_count = sizes.len;
+
+var zones: [zone_count]?*Zone = [_]?*Zone{null} ** zone_count;
+var initialized: bool = false;
+
+pub const AllocError = error{
+ NotInitialized,
+ SizeTooLarge,
+ OutOfMemory,
+};
+
+pub fn init() !void {
+ if (initialized) return;
+ if (!bootstrap.is_initialized()) return error.NotInitialized;
+
+ inline for (sizes, 0..) |size, i| {
+ zones[i] = try create_mod.create(zone_name(size), size);
+ }
+
+ initialized = true;
+}
+
+pub fn kalloc(size: usize) AllocError!*anyopaque {
+ if (!initialized) return AllocError.NotInitialized;
+ if (size == 0) return AllocError.SizeTooLarge;
+
+ const zone = get_zone_for_size(size) orelse return AllocError.SizeTooLarge;
+ return alloc_mod.zalloc(zone) catch AllocError.OutOfMemory;
+}
+
+pub fn kalloc_zeroed(size: usize) AllocError!*anyopaque {
+ if (!initialized) return AllocError.NotInitialized;
+ if (size == 0) return AllocError.SizeTooLarge;
+
+ const zone = get_zone_for_size(size) orelse return AllocError.SizeTooLarge;
+ return alloc_mod.zalloc_zeroed(zone) catch AllocError.OutOfMemory;
+}
+
+pub fn kfree(ptr: *anyopaque, size: usize) void {
+ if (!initialized) return;
+ const zone = get_zone_for_size(size) orelse return;
+ alloc_mod.zfree(zone, ptr);
+}
+
+fn get_zone_for_size(size: usize) ?*Zone {
+ inline for (sizes, 0..) |zone_size, i| {
+ if (size <= zone_size) return zones[i];
+ }
+ return null;
+}
+
+fn zone_name(comptime size: usize) []const u8 {
+ return switch (size) {
+ 16 => "kalloc.16",
+ 32 => "kalloc.32",
+ 64 => "kalloc.64",
+ 128 => "kalloc.128",
+ 256 => "kalloc.256",
+ 512 => "kalloc.512",
+ 1024 => "kalloc.1024",
+ 2048 => "kalloc.2048",
+ 4096 => "kalloc.4096",
+ else => "kalloc.unknown",
+ };
+}