Skip to content

Commit b967d48

Browse files
Add runtime page_size
1 parent 6734d21 commit b967d48

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,
@@ -449,6 +450,10 @@ pub const Target = struct {
449450
=> false,
450451
};
451452
}
453+
454+
pub fn compare(self: Os, other: Os) bool {
455+
return self.tag == other.tag and self.isAtLeast(other.tag, other.getVersionRange());
456+
}
452457
};
453458

454459
pub const aarch64 = @import("target/aarch64.zig");
@@ -1360,8 +1365,16 @@ pub const Target = struct {
13601365
pub fn baseline(arch: Arch) Cpu {
13611366
return Model.baseline(arch).toCpu(arch);
13621367
}
1368+
1369+
pub fn compare(self: Cpu, other: Cpu) bool {
1370+
return self.arch == other.arch and std.mem.eql(u8, self.model.name, other.model.name) and self.features.eql(other.features);
1371+
}
13631372
};
13641373

1374+
pub fn useHostPageSize(self: Target, other: Target) bool {
1375+
return self.cpu.compare(other.cpu) and self.os.compare(other.os);
1376+
}
1377+
13651378
pub fn zigTriple(self: Target, allocator: mem.Allocator) ![]u8 {
13661379
return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
13671380
}

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

@@ -176,6 +180,7 @@ pub fn toTarget(self: CrossTarget) Target {
176180
.os = self.getOs(),
177181
.abi = self.getAbi(),
178182
.ofmt = self.getObjectFormat(),
183+
.page_size = self.page_size,
179184
};
180185
}
181186

lib/std/zig/system/NativeTargetInfo.zig

+2
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ pub fn abiAndDynamicLinkerFromFile(
644644
.os = os,
645645
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
646646
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
647+
.page_size = cross_target.page_size,
647648
},
648649
.dynamic_linker = cross_target.dynamic_linker,
649650
};
@@ -921,6 +922,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: Cros
921922
.os = os,
922923
.abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
923924
.ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
925+
.page_size = cross_target.page_size,
924926
};
925927
return NativeTargetInfo{
926928
.target = target,

src/Compilation.zig

+3-1
Original file line numberDiff line numberDiff line change
@@ -6119,7 +6119,7 @@ pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
61196119
};
61206120
}
61216121

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

@@ -6267,6 +6267,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
62676267
\\ .os = os,
62686268
\\ .abi = abi,
62696269
\\ .ofmt = object_format,
6270+
\\ .page_size = {?},
62706271
\\}};
62716272
\\pub const object_format = std.Target.ObjectFormat.{};
62726273
\\pub const mode = std.builtin.OptimizeMode.{};
@@ -6282,6 +6283,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
62826283
\\pub const omit_frame_pointer = {};
62836284
\\
62846285
, .{
6286+
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),
62856287
std.zig.fmtId(@tagName(target.ofmt)),
62866288
std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),
62876289
link_libc,

0 commit comments

Comments
 (0)