-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
|
@@ -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, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
const std = @import("../std.zig"); | ||
const std = @import("std"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No underscore, please.