Commit 3487514626

jim price <shadeops@gmail.com>
2023-03-29 09:46:25
std.os: add mincore syscall
The mincore syscall is available on some UNIX like operating systems and allows a user to determine if a page is resident in memory.
1 parent 3e467c7
Changed files (3)
lib/std/c/linux.zig
@@ -289,6 +289,12 @@ pub extern "c" fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: *con
 pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
 pub extern "c" fn malloc_usable_size(?*const anyopaque) usize;
 
+pub extern "c" fn mincore(
+    addr: *align(std.mem.page_size) anyopaque,
+    length: usize,
+    vec: [*]u8,
+) c_int;
+
 pub extern "c" fn madvise(
     addr: *align(std.mem.page_size) anyopaque,
     length: usize,
lib/std/os/linux.zig
@@ -1699,6 +1699,10 @@ pub fn prlimit(pid: pid_t, resource: rlimit_resource, new_limit: ?*const rlimit,
     );
 }
 
+pub fn mincore(address: [*]u8, len: usize, vec: [*]u8) usize {
+    return syscall3(.mincore, @ptrToInt(address), len, @ptrToInt(vec));
+}
+
 pub fn madvise(address: [*]u8, len: usize, advice: u32) usize {
     return syscall3(.madvise, @ptrToInt(address), len, advice);
 }
lib/std/os.zig
@@ -6974,6 +6974,35 @@ pub fn setrlimit(resource: rlimit_resource, limits: rlimit) SetrlimitError!void
     }
 }
 
+pub const MincoreError = error{
+    /// A kernel resource was temporarily unavailable.
+    SystemResources,
+    /// vec points to an invalid address.
+    InvalidAddress,
+    /// addr is not page-aligned.
+    InvalidSyscall,
+    /// One of the following:
+    /// * length is greater than user space TASK_SIZE - addr
+    /// * addr + length contains unmapped memory
+    OutOfMemory,
+    /// The mincore syscall is not available on this version and configuration
+    /// of this UNIX-like kernel.
+    MincoreUnavailable,
+} || UnexpectedError;
+
+/// Determine whether pages are resident in memory.
+pub fn mincore(ptr: [*]align(mem.page_size) u8, length: usize, vec: [*]u8) MincoreError!void {
+    return switch (errno(system.mincore(ptr, length, vec))) {
+        .SUCCESS => {},
+        .AGAIN => error.SystemResources,
+        .FAULT => error.InvalidAddress,
+        .INVAL => error.InvalidSyscall,
+        .NOMEM => error.OutOfMemory,
+        .NOSYS => error.MincoreUnavailable,
+        else => |err| unexpectedErrno(err),
+    };
+}
+
 pub const MadviseError = error{
     /// advice is MADV.REMOVE, but the specified address range is not a shared writable mapping.
     AccessDenied,