diff --git a/std/c/darwin.zig b/std/c/darwin.zig index cbaa2f6811..c7e18d94cc 100644 --- a/std/c/darwin.zig +++ b/std/c/darwin.zig @@ -13,6 +13,10 @@ pub extern "c" fn kevent(kq: c_int, changelist: [*]const Kevent, nchanges: c_int pub extern "c" fn kevent64(kq: c_int, changelist: [*]const kevent64_s, nchanges: c_int, eventlist: [*]kevent64_s, nevents: c_int, flags: c_uint, timeout: ?*const timespec) c_int; +pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; +pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int; +pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int; + pub use @import("../os/darwin_errno.zig"); pub const _errno = __error; diff --git a/std/os/darwin.zig b/std/os/darwin.zig index 7921d1b6f0..fc933b7f47 100644 --- a/std/os/darwin.zig +++ b/std/os/darwin.zig @@ -520,6 +520,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { return errnoWrap(c.symlink(existing, new)); } +pub fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize { + return errnoWrap(c.sysctl(name, namelen, oldp, oldlenp, newp, newlen)); +} + +pub fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize { + return errnoWrap(c.sysctlbyname(name, oldp, oldlenp, newp, newlen)); +} + +pub fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) usize { + return errnoWrap(c.sysctlnametomib(name, wibp, sizep)); +} + pub fn rename(old: [*]const u8, new: [*]const u8) usize { return errnoWrap(c.rename(old, new)); } diff --git a/std/os/index.zig b/std/os/index.zig index 15594edcc8..0d0f63a066 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -2756,35 +2756,57 @@ pub const CpuCountError = error{ }; pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { - const usize_count = 16; - const allocator = std.heap.stackFallback(usize_count * @sizeOf(usize), fallback_allocator).get(); + switch (builtin.os) { + builtin.Os.macosx => { + var count: c_int = undefined; + var count_len: usize = @sizeOf(c_int); + const rc = posix.sysctlbyname(c"hw.ncpu", @ptrCast(*c_void, &count), &count_len, null, 0); + const err = posix.getErrno(rc); + switch (err) { + 0 => return @intCast(usize, count), + posix.EFAULT => unreachable, + posix.EINVAL => unreachable, + posix.ENOMEM => return CpuCountError.OutOfMemory, + posix.ENOTDIR => unreachable, + posix.EISDIR => unreachable, + posix.ENOENT => unreachable, + posix.EPERM => unreachable, + else => return os.unexpectedErrorPosix(err), + } + }, + builtin.Os.linux => { + const usize_count = 16; + const allocator = std.heap.stackFallback(usize_count * @sizeOf(usize), fallback_allocator).get(); - var set = try allocator.alloc(usize, usize_count); - defer allocator.free(set); + var set = try allocator.alloc(usize, usize_count); + defer allocator.free(set); - while (true) { - const rc = posix.sched_getaffinity(0, set); - const err = posix.getErrno(rc); - switch (err) { - 0 => { - if (rc < set.len * @sizeOf(usize)) { - const result = set[0 .. rc / @sizeOf(usize)]; - var sum: usize = 0; - for (result) |x| { - sum += @popCount(x); - } - return sum; - } else { - set = try allocator.realloc(usize, set, set.len * 2); - continue; + while (true) { + const rc = posix.sched_getaffinity(0, set); + const err = posix.getErrno(rc); + switch (err) { + 0 => { + if (rc < set.len * @sizeOf(usize)) { + const result = set[0 .. rc / @sizeOf(usize)]; + var sum: usize = 0; + for (result) |x| { + sum += @popCount(x); + } + return sum; + } else { + set = try allocator.realloc(usize, set, set.len * 2); + continue; + } + }, + posix.EFAULT => unreachable, + posix.EINVAL => unreachable, + posix.EPERM => return CpuCountError.PermissionDenied, + posix.ESRCH => unreachable, + else => return os.unexpectedErrorPosix(err), } - }, - posix.EFAULT => unreachable, - posix.EINVAL => unreachable, - posix.EPERM => return CpuCountError.PermissionDenied, - posix.ESRCH => unreachable, - else => return os.unexpectedErrorPosix(err), - } + } + }, + else => @compileError("unsupported OS"), } }