Commit 01a7affb87

Andrew Kelley <andrew@ziglang.org>
2020-09-17 05:18:06
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).
1 parent 07eb2c6
Changed files (2)
src-self-hosted
src-self-hosted/main.zig
@@ -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();
+}
BRANCH_TODO
@@ -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