summaryrefslogtreecommitdiff
path: root/src/mem.zig
blob: b361b88397439a73e3982d35bb00472a4e2c48fc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const std = @import("std");

const Page = extern struct {
    next: *Page,
};

var head = @extern(*align(4096) Page, .{ .name = "_heap_start" });

pub fn init() void {
    // how many pages do we have?
    const page_count = @intFromPtr(@extern(
        *const anyopaque,
        .{ .name = "_heap_size" },
    )) / 4096;

    // go through every page and make it point it to the next one
    const pages: []Page = @as([*]Page, @ptrCast(head))[0..page_count];
    for (0..page_count - 1) |i| {
        pages[i].next = &pages[i + 1];
    }

    std.log.scoped(.mem).info(
        "{} physical pages of 4096 B = {} B free",
        .{ page_count, page_count * 4096 },
    );
}

// allocates 1 page by taking it off the front of the linked list
pub fn alloc() []align(4096) u8 {
    const page = @as([*]align(4096) u8, @ptrCast(head))[0..4096];
    head = head.next;
    return page;
}

// free the page by putting it back on the front of the linked list
pub fn free(mem: []align(4096) u8) void {
    std.debug.assert(mem.len == 4096);
    const page: *Page = @ptrCast(mem.ptr);
    page.next = head;
    head = page;
}