diff options
| -rw-r--r-- | lib/std/os/bits/darwin.zig | 3 | ||||
| -rw-r--r-- | src/main.zig | 52 | ||||
| -rw-r--r-- | src/stage1/os.cpp | 23 |
3 files changed, 30 insertions, 48 deletions
diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig index a30d11fcd1..3e4149decd 100644 --- a/lib/std/os/bits/darwin.zig +++ b/lib/std/os/bits/darwin.zig @@ -1475,6 +1475,9 @@ pub const CLOCK_UPTIME_RAW_APPROX = 9; pub const CLOCK_PROCESS_CPUTIME_ID = 12; pub const CLOCK_THREAD_CPUTIME_ID = 16; +/// Max open files per process +/// https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/syslimits.h.auto.html +pub const OPEN_MAX = 10240; pub const RUSAGE_SELF = 0; pub const RUSAGE_CHILDREN = -1; diff --git a/src/main.zig b/src/main.zig index 45fcb5ce61..7df8cb1eda 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2982,35 +2982,37 @@ fn parseCodeModel(arg: []const u8) std.builtin.CodeModel { /// 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, - } + if (!@hasDecl(std.os, "rlimit")) return; const posix = std.os; - var lim = posix.getrlimit(posix.RLIMIT_NOFILE, &lim) catch return; // Oh well; we tried. + + var lim = posix.getrlimit(.NOFILE) catch return; // Oh well; we tried. + if (comptime std.Target.current.isDarwin()) { + // On Darwin, `NOFILE` is bounded by a hardcoded value `OPEN_MAX`. + // According to the man pages for setrlimit(): + // setrlimit() now returns with errno set to EINVAL in places that historically succeeded. + // It no longer accepts "rlim_cur = RLIM_INFINITY" for RLIM_NOFILE. + // Use "rlim_cur = min(OPEN_MAX, rlim_max)". + lim.max = std.math.min(std.os.darwin.OPEN_MAX, lim.max); + } if (lim.cur == lim.max) return; + + // 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) { - // 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; + lim.cur = min + @divTrunc(max - min, 2); // on freebsd rlim_t is signed + if (posix.setrlimit(.NOFILE, lim)) |_| { + min = lim.cur; + } else |_| { + max = lim.cur; } + if (min + 1 >= max) break; } } diff --git a/src/stage1/os.cpp b/src/stage1/os.cpp index c9dd49071c..1cb015c1af 100644 --- a/src/stage1/os.cpp +++ b/src/stage1/os.cpp @@ -978,29 +978,6 @@ int os_init(void) { host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &macos_monotonic_clock); host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &macos_calendar_clock); #endif -#if defined(ZIG_OS_POSIX) - // Raise the open file descriptor limit. - // Code lifted from node.js - struct rlimit lim; - if (getrlimit(RLIMIT_NOFILE, &lim) == 0 && lim.rlim_cur != lim.rlim_max) { - // Do a binary search for the limit. - rlim_t min = lim.rlim_cur; - rlim_t max = 1 << 20; - // But if there's a defined upper bound, don't search, just set it. - if (lim.rlim_max != RLIM_INFINITY) { - min = lim.rlim_max; - max = lim.rlim_max; - } - do { - lim.rlim_cur = min + (max - min) / 2; - if (setrlimit(RLIMIT_NOFILE, &lim)) { - max = lim.rlim_cur; - } else { - min = lim.rlim_cur; - } - } while (min + 1 < max); - } -#endif return 0; } |
