Skip to content

Commit 0242d33

Browse files
Add runtime page_size
1 parent ad168db commit 0242d33

File tree

10 files changed

+155
-8
lines changed

10 files changed

+155
-8
lines changed

lib/std/c.zig

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub usingnamespace switch (builtin.os.tag) {
7979
pub extern "c" fn getrusage(who: c_int, usage: *c.rusage) c_int;
8080

8181
pub extern "c" fn sched_yield() c_int;
82+
pub extern "c" fn sysconf(sc: c_int) c_long;
8283

8384
pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const c.Sigaction, noalias oact: ?*c.Sigaction) c_int;
8485
pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const c.sigset_t, noalias oset: ?*c.sigset_t) c_int;

lib/std/mem.zig

+58-7
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,67 @@ const testing = std.testing;
1010
const Endian = std.builtin.Endian;
1111
const native_endian = builtin.cpu.arch.endian();
1212

13+
pub const PageSizeCheck = enum {
14+
/// Does nothing if the page size is invalid
15+
unsafe,
16+
/// Throws an error if the page size is invalid
17+
throw,
18+
/// Asserts if the page size is invalid
19+
assert,
20+
/// Panics if the page size is invalid
21+
panic,
22+
23+
pub fn makeType(comptime self: PageSizeCheck) type {
24+
return switch (self) {
25+
.assert, .unsafe, .panic => usize,
26+
.throw => error{InvalidPageSize}!usize,
27+
};
28+
}
29+
};
30+
31+
pub const PageSizeOptions = struct {
32+
/// Value sanity check method
33+
check: PageSizeCheck = .assert,
34+
/// Use the comptime version of page size if the OS does not report it.
35+
comptime_fallback: bool = true,
36+
};
37+
38+
/// Runtime known minimum page size.
39+
pub fn getPageSize(comptime options: PageSizeOptions) PageSizeCheck.makeType(options.check) {
40+
const value: usize = switch (builtin.os.tag) {
41+
.linux => if (builtin.link_libc) @intCast(std.c.sysconf(std.os.linux.SC.PAGESIZE)) else std.os.linux.getauxval(std.elf.AT_PAGESZ),
42+
else => if (options.comptime_fallback) page_size else 0,
43+
};
44+
45+
return switch (options.check) {
46+
.unsafe => value,
47+
.assert => {
48+
assert(value != 0);
49+
return value;
50+
},
51+
.panic => {
52+
if (value == 0) @panic("Invalid page size");
53+
return value;
54+
},
55+
.throw => if (value == 0) return error.InvalidPageSize else value,
56+
};
57+
}
58+
1359
/// Compile time known minimum page size.
1460
/// https://github.com/ziglang/zig/issues/4082
15-
pub const page_size = switch (builtin.cpu.arch) {
16-
.wasm32, .wasm64 => 64 * 1024,
17-
.aarch64 => switch (builtin.os.tag) {
18-
.macos, .ios, .watchos, .tvos => 16 * 1024,
61+
pub const page_size = blk: {
62+
const value = builtin.target.page_size orelse switch (builtin.cpu.arch) {
63+
.wasm32, .wasm64 => 64 * 1024,
64+
.aarch64 => switch (builtin.os.tag) {
65+
.macos, .ios, .watchos, .tvos => 16 * 1024,
66+
else => 4 * 1024,
67+
},
68+
.sparc64 => 8 * 1024,
1969
else => 4 * 1024,
20-
},
21-
.sparc64 => 8 * 1024,
22-
else => 4 * 1024,
70+
};
71+
72+
if (value == 0) @compileError("Page size is not valid");
73+
break :blk value;
2374
};
2475

2576
/// The standard library currently thoroughly depends on byte size

lib/std/os/linux/arm-eabi.zig

+24
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,27 @@ pub const ucontext_t = extern struct {
356356
};
357357

358358
pub const Elf_Symndx = u32;
359+
360+
pub const SC = struct {
361+
pub const socket = 1;
362+
pub const bind = 2;
363+
pub const connect = 3;
364+
pub const listen = 4;
365+
pub const accept = 5;
366+
pub const getsockname = 6;
367+
pub const getpeername = 7;
368+
pub const socketpair = 8;
369+
pub const send = 9;
370+
pub const recv = 10;
371+
pub const sendto = 11;
372+
pub const recvfrom = 12;
373+
pub const shutdown = 13;
374+
pub const setsockopt = 14;
375+
pub const getsockopt = 15;
376+
pub const sendmsg = 16;
377+
pub const recvmsg = 17;
378+
pub const accept4 = 18;
379+
pub const recvmmsg = 19;
380+
pub const sendmmsg = 20;
381+
pub const PAGESIZE = 30;
382+
};

lib/std/os/linux/arm64.zig

+24
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,27 @@ pub const ucontext_t = extern struct {
301301
};
302302

303303
pub const Elf_Symndx = u32;
304+
305+
pub const SC = struct {
306+
pub const socket = 1;
307+
pub const bind = 2;
308+
pub const connect = 3;
309+
pub const listen = 4;
310+
pub const accept = 5;
311+
pub const getsockname = 6;
312+
pub const getpeername = 7;
313+
pub const socketpair = 8;
314+
pub const send = 9;
315+
pub const recv = 10;
316+
pub const sendto = 11;
317+
pub const recvfrom = 12;
318+
pub const shutdown = 13;
319+
pub const setsockopt = 14;
320+
pub const getsockopt = 15;
321+
pub const sendmsg = 16;
322+
pub const recvmsg = 17;
323+
pub const accept4 = 18;
324+
pub const recvmmsg = 19;
325+
pub const sendmmsg = 20;
326+
pub const PAGESIZE = 30;
327+
};

lib/std/os/linux/x86.zig

+1
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ pub const SC = struct {
385385
pub const accept4 = 18;
386386
pub const recvmmsg = 19;
387387
pub const sendmmsg = 20;
388+
pub const PAGESIZE = 30;
388389
};
389390

390391
fn gpRegisterOffset(comptime reg_index: comptime_int) usize {

lib/std/os/linux/x86_64.zig

+24
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,27 @@ pub inline fn getcontext(context: *ucontext_t) usize {
489489
: "cc", "memory", "rcx", "rdx", "rsi", "r8", "r10", "r11"
490490
);
491491
}
492+
493+
pub const SC = struct {
494+
pub const socket = 1;
495+
pub const bind = 2;
496+
pub const connect = 3;
497+
pub const listen = 4;
498+
pub const accept = 5;
499+
pub const getsockname = 6;
500+
pub const getpeername = 7;
501+
pub const socketpair = 8;
502+
pub const send = 9;
503+
pub const recv = 10;
504+
pub const sendto = 11;
505+
pub const recvfrom = 12;
506+
pub const shutdown = 13;
507+
pub const setsockopt = 14;
508+
pub const getsockopt = 15;
509+
pub const sendmsg = 16;
510+
pub const recvmsg = 17;
511+
pub const accept4 = 18;
512+
pub const recvmmsg = 19;
513+
pub const sendmmsg = 20;
514+
pub const PAGESIZE = 30;
515+
};

lib/std/target.zig

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub const Target = struct {
88
os: Os,
99
abi: Abi,
1010
ofmt: ObjectFormat,
11+
page_size: ?usize = null,
1112

1213
pub const Os = struct {
1314
tag: Tag,
@@ -456,6 +457,10 @@ pub const Target = struct {
456457
=> false,
457458
};
458459
}
460+
461+
pub fn compare(self: Os, other: Os) bool {
462+
return self.tag == other.tag and self.isAtLeast(other.tag, other.getVersionRange());
463+
}
459464
};
460465

461466
pub const aarch64 = @import("target/aarch64.zig");
@@ -1368,8 +1373,16 @@ pub const Target = struct {
13681373
pub fn baseline(arch: Arch) Cpu {
13691374
return Model.baseline(arch).toCpu(arch);
13701375
}
1376+
1377+
pub fn compare(self: Cpu, other: Cpu) bool {
1378+
return self.arch == other.arch and std.mem.eql(u8, self.model.name, other.model.name) and self.features.eql(other.features);
1379+
}
13711380
};
13721381

1382+
pub fn useHostPageSize(self: Target, other: Target) bool {
1383+
return self.cpu.compare(other.cpu) and self.os.compare(other.os);
1384+
}
1385+
13731386
pub fn zigTriple(self: Target, allocator: mem.Allocator) ![]u8 {
13741387
return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
13751388
}

lib/std/zig/CrossTarget.zig

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ dynamic_linker: DynamicLinker = DynamicLinker{},
4545
/// `null` means default for the cpu/arch/os combo.
4646
ofmt: ?Target.ObjectFormat = null,
4747

48+
/// `null` means to dynamically get the page size or use the platform default.
49+
page_size: ?usize = null,
50+
4851
pub const CpuModel = union(enum) {
4952
/// Always native
5053
native,
@@ -81,6 +84,7 @@ pub fn fromTarget(target: Target) CrossTarget {
8184
target.os.version_range.linux.glibc
8285
else
8386
null,
87+
.page_size = target.page_size,
8488
};
8589
result.updateOsVersionRange(target.os);
8690

@@ -177,6 +181,7 @@ pub fn toTarget(self: CrossTarget) Target {
177181
.os = self.getOs(),
178182
.abi = self.getAbi(),
179183
.ofmt = self.getObjectFormat(),
184+
.page_size = self.page_size,
180185
};
181186
}
182187

lib/std/zig/system/NativeTargetInfo.zig

+2
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,7 @@ pub fn abiAndDynamicLinkerFromFile(
646646
.os = os,
647647
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
648648
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
649+
.page_size = cross_target.page_size,
649650
},
650651
.dynamic_linker = cross_target.dynamic_linker,
651652
};
@@ -923,6 +924,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros
923924
.os = os,
924925
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
925926
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
927+
.page_size = cross_target.page_size,
926928
};
927929
return NativeTargetInfo{
928930
.target = target,

src/Compilation.zig

+3-1
Original file line numberDiff line numberDiff line change
@@ -6233,7 +6233,7 @@ pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
62336233
};
62346234
}
62356235

6236-
pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![:0]u8 {
6236+
pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) error{ OutOfMemory, InvalidPageSize }![:0]u8 {
62376237
const tracy_trace = trace(@src());
62386238
defer tracy_trace.end();
62396239

@@ -6381,6 +6381,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
63816381
\\ .os = os,
63826382
\\ .abi = abi,
63836383
\\ .ofmt = object_format,
6384+
\\ .page_size = {?},
63846385
\\}};
63856386
\\pub const object_format = std.Target.ObjectFormat.{};
63866387
\\pub const mode = std.builtin.OptimizeMode.{};
@@ -6396,6 +6397,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
63966397
\\pub const omit_frame_pointer = {};
63976398
\\
63986399
, .{
6400+
target.page_size orelse (if (comp.bin_file.options.is_native_os and comp.bin_file.options.is_native_abi) try std.mem.getPageSize(.{ .check = .throw }) else null),
63996401
std.zig.fmtId(@tagName(target.ofmt)),
64006402
std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),
64016403
link_libc,

0 commit comments

Comments
 (0)