stage2: ask for a higher open fd limit

Here's the doc comment from the commit:

For one example of why this is handy, consider the case of building musl libc.
We keep a lock open for each of the object files in the form of a file descriptor
until they are finally put into an archive file. This is to allow a zig-cache
garbage collector to run concurrently to zig processes, and to allow multiple
zig processes to run concurrently with each other, without clobbering each other.

This code is disabled until #6361 is implemented (getrlimit/setrlimit
are not yet added to the standard library).
This commit is contained in:
Andrew Kelley 2020-09-16 20:18:06 -07:00
parent 07eb2c65f6
commit 01a7affb87
2 changed files with 45 additions and 1 deletions

View File

@ -12,7 +12,6 @@
* capture lld stdout/stderr better
* musl
* mingw-w64
* port the stage1 os.cpp code that raises the open fd limit
* use global zig-cache dir for crt files
* `zig translate-c`
* MachO LLD linking

View File

@ -1103,6 +1103,8 @@ pub fn buildOutputType(
},
};
gimmeMoreOfThoseSweetSweetFileDescriptors();
const comp = Compilation.create(gpa, .{
.zig_lib_directory = zig_lib_directory,
.zig_cache_directory = zig_cache_directory,
@ -1930,3 +1932,46 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel {
return std.meta.stringToEnum(std.builtin.CodeModel, arg) orelse
fatal("unsupported machine code model: '{}'", .{arg});
}
/// Raise the open file descriptor limit. Ask and ye shall receive.
/// For one example of why this is handy, consider the case of building musl libc.
/// We keep a lock open for each of the object files in the form of a file descriptor
/// until they are finally put into an archive file. This is to allow a zig-cache
/// garbage collector to run concurrently to zig processes, and to allow multiple
/// zig processes to run concurrently with each other, without clobbering each other.
fn gimmeMoreOfThoseSweetSweetFileDescriptors() void {
switch (std.Target.current.os.tag) {
.windows, .wasi, .uefi, .other, .freestanding => return,
// std lib is missing getrlimit/setrlimit.
// https://github.com/ziglang/zig/issues/6361
//else => {},
else => return,
}
const posix = std.os;
var lim = posix.getrlimit(posix.RLIMIT_NOFILE, &lim) catch return; // Oh well; we tried.
if (lim.cur == lim.max) return;
while (true) {
// Do a binary search for the limit.
var min: posix.rlim_t = lim.cur;
var max: posix.rlim_t = 1 << 20;
// But if there's a defined upper bound, don't search, just set it.
if (lim.max != posix.RLIM_INFINITY) {
min = lim.max;
max = lim.max;
}
while (true) {
lim.cur = min + (max - min) / 2;
if (posix.setrlimit(posix.RLIMIT_NOFILE, lim)) |_| {
min = lim.cur;
} else |_| {
max = lim.cur;
}
if (min + 1 < max) continue;
return;
}
}
}
test "fds" {
gimmeMoreOfThoseSweetSweetFileDescriptors();
}