aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/std/os/bits/darwin.zig3
-rw-r--r--src/main.zig52
-rw-r--r--src/stage1/os.cpp23
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;
}