Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Last active August 30, 2024 16:50
Show Gist options
  • Save ityonemo/f2fb21228a365fbd6d38939712ae16b6 to your computer and use it in GitHub Desktop.
Save ityonemo/f2fb21228a365fbd6d38939712ae16b6 to your computer and use it in GitHub Desktop.
numa - aware allocation in zig
const std = @import("std");
const posix = std.posix;
const numaif = @cImport({
@cInclude("numaif.h");
@cInclude("errno.h");
});
extern threadlocal var errno: c_int;
fn numa_alloc(size: usize, node: ?u1) ![]align(std.mem.page_size) u8 {
const hint = @atomicLoad(@TypeOf(std.heap.next_mmap_addr_hint), &std.heap.next_mmap_addr_hint, .unordered);
const slice = try posix.mmap(
hint,
size,
posix.PROT.READ | posix.PROT.WRITE,
.{ .TYPE = .PRIVATE, .ANONYMOUS = true },
-1,
0,
);
errdefer posix.munmap(slice);
const nodemask = @as(u64, 1) << node.?;
const mbind_result = numaif.mbind(slice.ptr, size, numaif.MPOL_BIND, &nodemask, 2, 0);
const Binderror = enum {FAULT, INVAL, IO, NOMEM, EPERM};
if (mbind_result != 0) {
const err: Binderror = switch (errno) {
numaif.EFAULT => .FAULT,
numaif.EINVAL => .INVAL,
numaif.EIO => .IO,
numaif.ENOMEM => .NOMEM,
numaif.EPERM => .EPERM,
else => {
std.debug.print("error {}\n", .{errno});
return error.mbind_fail;
}
};
std.debug.print("bind failed with: {}\n", .{err});
return error.mbind_fail;
} else {
return slice;
}
}
fn numa_free(slice: []align(std.mem.page_size) u8) void {
posix.munmap(slice);
}
pub fn main() !void {
const mem1 = try numa_alloc(4096, 0);
std.debug.print("mem1: {*}\n", .{mem1});
numa_free(mem1);
const mem2 = try numa_alloc(4096, 1);
std.debug.print("mem2: {*}\n", .{mem2});
numa_free(mem2);
}
@ityonemo
Copy link
Author

ityonemo commented Aug 30, 2024

run:

isaac@andoria-08:~$ zig run -lc -lnuma test.zig
mem1: u8@7f2b0be69000
bind failed with: test.numa_alloc.Binderror.INVAL
error: mbind_fail
/home/isaac/test.zig:39:8: 0x1032cff in numa_alloc (test)
      return error.mbind_fail; 
      ^
/home/isaac/test.zig:54:17: 0x10339fa in main (test)
  const mem2 = try numa_alloc(4096, 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment