Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std.os: add sysconf(), getDefaultPageSize() with smoke tests #16638

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/std/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub usingnamespace switch (builtin.os.tag) {

pub extern "c" fn getrusage(who: c_int, usage: *c.rusage) c_int;

pub extern "c" fn sysconf(sc: c_int) c_long;
pub extern "c" fn sched_yield() c_int;

pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const c.Sigaction, noalias oact: ?*c.Sigaction) c_int;
Expand Down
5 changes: 4 additions & 1 deletion lib/std/c/darwin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ pub const mach_header_64 = macho.mach_header_64;
pub const mach_header = macho.mach_header;

pub const _errno = __error;
pub const _SC = struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No underscore, please.

pub const PAGESIZE = 29;
};

pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int;
pub extern "c" fn mach_host_self() mach_port_t;
Expand Down Expand Up @@ -3691,7 +3694,7 @@ pub const MachTask = extern struct {
return left;
}

fn getPageSize(task: MachTask) MachError!usize {
pub fn getPageSize(task: MachTask) MachError!usize {
if (task.isValid()) {
var info_count = TASK_VM_INFO_COUNT;
var vm_info: task_vm_info_data_t = undefined;
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/dragonfly.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub fn _errno() *c_int {
return &errno;
}

pub const _SC = struct {
pub const PAGESIZE = 47;
};

pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/freebsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const iovec_const = std.os.iovec_const;
extern "c" fn __error() *c_int;
pub const _errno = __error;

pub const _SC = struct {
pub const PAGESIZE = 47;
};

pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) isize;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
Expand Down
5 changes: 5 additions & 0 deletions lib/std/c/fuchsia.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// third party ulib musl
pub const _SC = struct {
pub const PAGESIZE = 30;
};

pub const pthread_mutex_t = extern struct {
size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
};
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/haiku.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ extern "c" fn _errnop() *c_int;

pub const _errno = _errnop;

pub const _SC = struct {
pub const PAGESIZE = 27;
};

pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;

pub extern "c" fn find_thread(thread_name: ?*anyopaque) i32;
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/hermit.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
const std = @import("std");
const maxInt = std.math.maxInt;

// pub const _SC = struct {
// pub const PAGESIZE = TODO;
// };

pub const pthread_mutex_t = extern struct {
inner: usize = ~@as(usize, 0),
};
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/linux.zig
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ pub const user_desc = linux.user_desc;
pub const utsname = linux.utsname;
pub const PR = linux.PR;

pub const _SC = struct {
pub const PAGESIZE = 30;
};

pub const _errno = switch (native_abi) {
.android => struct {
extern fn __errno() *c_int;
Expand Down
5 changes: 5 additions & 0 deletions lib/std/c/minix.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
const builtin = @import("builtin");

pub const _SC = struct {
pub const PAGESIZE = 28;
};

pub const pthread_mutex_t = extern struct {
size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
};
Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/netbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ const rusage = std.c.rusage;
extern "c" fn __errno() *c_int;
pub const _errno = __errno;

pub const _SC = struct {
pub const PAGESIZE = 28;
};

pub const dl_iterate_phdr_callback = *const fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;

Expand Down
4 changes: 4 additions & 0 deletions lib/std/c/openbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const iovec_const = std.os.iovec_const;
extern "c" fn __errno() *c_int;
pub const _errno = __errno;

pub const _SC = struct {
pub const PAGESIZE = 28;
};

pub const dl_iterate_phdr_callback = *const fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;

Expand Down
11 changes: 5 additions & 6 deletions lib/std/c/solaris.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const timezone = std.c.timezone;
extern "c" fn ___errno() *c_int;
pub const _errno = ___errno;

pub const _SC = struct {
pub const PAGESIZE = 11;
pub const NPROCESSORS_ONLN = 15;
};

pub const dl_iterate_phdr_callback = *const fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int;

Expand All @@ -17,7 +22,6 @@ pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int;
pub extern "c" fn sysconf(sc: c_int) i64;
pub extern "c" fn signalfd(fd: fd_t, mask: *const sigset_t, flags: u32) c_int;
pub extern "c" fn madvise(address: [*]u8, len: usize, advise: u32) c_int;

Expand Down Expand Up @@ -1684,11 +1688,6 @@ pub const AF_SUN = struct {
pub const NOPLM = 0x00000004;
};

// TODO: Add sysconf numbers when the other OSs do.
pub const _SC = struct {
pub const NPROCESSORS_ONLN = 15;
};

pub const procfs = struct {
pub const misc_header = extern struct {
size: u32,
Expand Down
67 changes: 67 additions & 0 deletions lib/std/os.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4337,6 +4337,47 @@ pub fn fork() ForkError!pid_t {
}
}

/// Returns page size assigned by the Kernel to the process. This size is
/// constant during process lifetime, but other page sizes might be usable.
pub fn getDefaultPageSize() error{UnknownPageSize}!usize {
Comment on lines +4340 to +4342
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not belong in std.os (reminder: #5019)

I think it should go into std.heap.pageSize.

switch (builtin.cpu.arch) { // archs with fixed size page size
.wasm32, .wasm64 => return 64 * 1024,
else => {},
}

switch (builtin.os.tag) { // kernel chooses the page size
.linux => {
if (builtin.link_libc) {
return sysconf(std.c._SC.PAGESIZE) catch return error.UnknownPageSize;
} else {
return linux.getauxval(std.elf.AT_PAGESZ);
}
},
.windows => {
var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined;
const rc = std.os.windows.ntdll.NtQuerySystemInformation(
.SystemBasicInformation,
&sbi,
@sizeOf(std.os.windows.SYSTEM_BASIC_INFORMATION),
null,
);
if (rc != .SUCCESS) {
return error.UnknownPageSize;
}
return sbi.PageSize;
},
// zig fmt: off
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to turn off formatting

.dragonfly, .freebsd, .fuchsia, .haiku,
.macos, .ios, .watchos, .tvos,
.minix, .netbsd, .openbsd, .solaris, => {
return sysconf(std.c._SC.PAGESIZE) catch return error.UnknownPageSize;
},
// zig fmt: on
// TODO .hermit (no reliable page size and api yet)
else => unreachable,
}
}

pub const MMapError = error{
/// The underlying filesystem of the specified file does not support memory mapping.
MemoryMappingNotSupported,
Expand Down Expand Up @@ -4682,6 +4723,32 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {
return fds;
}

pub const SysConfError = error{
NoLimit,
InvalidName, // To probe compiletime or runtime support
} || UnexpectedError;

pub fn sysconf(sc: c_int) SysConfError!usize {
const limit: isize = std.c.sysconf(sc);
const is_minus_one = @clz(limit) == 0; // -1 only possible negative value <=> clz(-1) == 0
const is_inval = isinval: {
switch (errno(limit)) {
.SUCCESS => break :isinval false,
.INVAL => break :isinval true,
else => |err| return unexpectedErrno(err),
}
};
var choice: u8 = 0;
choice += @intFromBool(is_minus_one);
choice += @intFromBool(is_inval);
switch (choice) {
0 => return @bitCast(limit),
1 => return error.NoLimit, // sysconf -1, errno not set
2 => return error.InvalidName, // sysconf -1, errno EINVAL
else => unreachable,
}
}

pub const SysCtlError = error{
PermissionDenied,
SystemResources,
Expand Down
13 changes: 12 additions & 1 deletion lib/std/os/test.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const std = @import("../std.zig");
const std = @import("std");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be left alone

const os = std.os;
const testing = std.testing;
const expect = testing.expect;
Expand Down Expand Up @@ -1219,3 +1219,14 @@ test "fchmodat smoke test" {
const st = try os.fstatat(tmp.dir.fd, "foo.txt", 0);
try expectEqual(@as(os.mode_t, 0o755), st.mode & 0b111_111_111);
}

test "getDefaultPageSize smoke test" {
const page_size = try os.getDefaultPageSize();
switch (page_size) {
// zig fmt: off
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not turn off code formatting

1024, 2048, 4096, 8192, 16384, 32768, 65536, // 1, 2, 4, 8, 16, 32, 64KB
2097152, 4194304 => {}, // 2, 4MB
// zig fmt: on
else => return error.InvalidDefaultPageSize,
}
}