lib/gpalloc/src/page/mapping.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const config = @import("../root.zig").config;
3 const sys = @import("sys");
4 const model = @import("model.zig");
5
6 const Allocator = std.mem.Allocator;
7 const Page = model.Page;
8 const page_size = config.page_size;
9
10 pub fn createFromBacking(backing_allocator: Allocator, class_index: usize, ret_addr: usize) ?*Page {
11 const memory = backing_allocator.rawAlloc(page_size, .fromByteUnits(page_size), ret_addr) orelse return null;
12 const page: *Page = @ptrCast(@alignCast(memory));
13 Page.init(page, class_index, @ptrCast(@alignCast(memory)), page_size);
14 return page;
15 }
16
17 pub fn destroyInBacking(backing_allocator: Allocator, page: *Page, ret_addr: usize) void {
18 page.magic = 0;
19 backing_allocator.rawFree(page.allocationSlice(), .fromByteUnits(page_size), ret_addr);
20 }
21
22 pub fn createFromOs(class_index: usize) ?*Page {
23 const mapping = sys.memory.mapAnonymous(page_size * 2, .{ .read = true, .write = true }) catch return null;
24 const mapping_addr = @intFromPtr(mapping.ptr);
25 const page_addr = std.mem.alignForward(usize, mapping_addr, page_size);
26 const page_offset = page_addr - mapping_addr;
27 const page_end = page_offset + page_size;
28 std.debug.assert(page_end <= mapping.len);
29
30 if (page_offset > 0) sys.memory.unmap(mapping[0..page_offset]);
31 if (page_end < mapping.len) {
32 const suffix: [*]align(std.heap.page_size_min) u8 = @ptrFromInt(mapping_addr + page_end);
33 sys.memory.unmap(suffix[0 .. mapping.len - page_end]);
34 }
35
36 const page: *Page = @ptrFromInt(page_addr);
37 const page_mapping: [*]align(std.heap.page_size_min) u8 = @ptrFromInt(page_addr);
38 Page.init(page, class_index, page_mapping, page_size);
39 return page;
40 }
41
42 pub fn destroyFromOs(page: *Page) void {
43 const mapping = page.mappingSlice();
44 page.magic = 0;
45 sys.memory.unmap(mapping);
46 }
47
48 pub fn fromBlock(ptr: [*]u8) *Page {
49 const page_addr = std.mem.alignBackward(usize, @intFromPtr(ptr), page_size);
50 return @ptrFromInt(page_addr);
51 }
52
53 test {
54 std.testing.refAllDecls(@This());
55 }