authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-09 01:08:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-09 01:08:33-04:00
log04d3da4bd1d5b8922d3f161c92c6185f33961523
treeb4c068207f673fa1e698c23c46f36c94c8db7e24
parent50d70d5f498470790f6d58b5e3018e0d89c2c9f3

std.os.cpuCount implementation for macos


3 files changed, 64 insertions(+), 26 deletions(-)

std/c/darwin.zig+4
...@@ -13,6 +13,10 @@ pub extern "c" fn kevent(kq: c_int, changelist: [*]const Kevent, nchanges: c_int...@@ -13,6 +13,10 @@ pub extern "c" fn kevent(kq: c_int, changelist: [*]const Kevent, nchanges: c_int
13pub extern "c" fn kevent64(kq: c_int, changelist: [*]const kevent64_s, nchanges: c_int,13pub extern "c" fn kevent64(kq: c_int, changelist: [*]const kevent64_s, nchanges: c_int,
14 eventlist: [*]kevent64_s, nevents: c_int, flags: c_uint, timeout: ?*const timespec) c_int;14 eventlist: [*]kevent64_s, nevents: c_int, flags: c_uint, timeout: ?*const timespec) c_int;
1515
16pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
17pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
18pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
19
16pub use @import("../os/darwin_errno.zig");20pub use @import("../os/darwin_errno.zig");
1721
18pub const _errno = __error;22pub const _errno = __error;
std/os/darwin.zig+12
...@@ -520,6 +520,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {...@@ -520,6 +520,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
520 return errnoWrap(c.symlink(existing, new));520 return errnoWrap(c.symlink(existing, new));
521}521}
522522
523pub fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
524 return errnoWrap(c.sysctl(name, namelen, oldp, oldlenp, newp, newlen));
525}
526
527pub fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) usize {
528 return errnoWrap(c.sysctlbyname(name, oldp, oldlenp, newp, newlen));
529}
530
531pub fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) usize {
532 return errnoWrap(c.sysctlnametomib(name, wibp, sizep));
533}
534
523pub fn rename(old: [*]const u8, new: [*]const u8) usize {535pub fn rename(old: [*]const u8, new: [*]const u8) usize {
524 return errnoWrap(c.rename(old, new));536 return errnoWrap(c.rename(old, new));
525}537}
std/os/index.zig+48-26
...@@ -2756,35 +2756,57 @@ pub const CpuCountError = error{...@@ -2756,35 +2756,57 @@ pub const CpuCountError = error{
2756};2756};
27572757
2758pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {2758pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
2759 const usize_count = 16;2759 switch (builtin.os) {
2760 const allocator = std.heap.stackFallback(usize_count * @sizeOf(usize), fallback_allocator).get();2760 builtin.Os.macosx => {
2761 var count: c_int = undefined;
2762 var count_len: usize = @sizeOf(c_int);
2763 const rc = posix.sysctlbyname(c"hw.ncpu", @ptrCast(*c_void, &count), &count_len, null, 0);
2764 const err = posix.getErrno(rc);
2765 switch (err) {
2766 0 => return @intCast(usize, count),
2767 posix.EFAULT => unreachable,
2768 posix.EINVAL => unreachable,
2769 posix.ENOMEM => return CpuCountError.OutOfMemory,
2770 posix.ENOTDIR => unreachable,
2771 posix.EISDIR => unreachable,
2772 posix.ENOENT => unreachable,
2773 posix.EPERM => unreachable,
2774 else => return os.unexpectedErrorPosix(err),
2775 }
2776 },
2777 builtin.Os.linux => {
2778 const usize_count = 16;
2779 const allocator = std.heap.stackFallback(usize_count * @sizeOf(usize), fallback_allocator).get();
27612780
2762 var set = try allocator.alloc(usize, usize_count);2781 var set = try allocator.alloc(usize, usize_count);
2763 defer allocator.free(set);2782 defer allocator.free(set);
27642783
2765 while (true) {2784 while (true) {
2766 const rc = posix.sched_getaffinity(0, set);2785 const rc = posix.sched_getaffinity(0, set);
2767 const err = posix.getErrno(rc);2786 const err = posix.getErrno(rc);
2768 switch (err) {2787 switch (err) {
2769 0 => {2788 0 => {
2770 if (rc < set.len * @sizeOf(usize)) {2789 if (rc < set.len * @sizeOf(usize)) {
2771 const result = set[0 .. rc / @sizeOf(usize)];2790 const result = set[0 .. rc / @sizeOf(usize)];
2772 var sum: usize = 0;2791 var sum: usize = 0;
2773 for (result) |x| {2792 for (result) |x| {
2774 sum += @popCount(x);2793 sum += @popCount(x);
2775 }2794 }
2776 return sum;2795 return sum;
2777 } else {2796 } else {
2778 set = try allocator.realloc(usize, set, set.len * 2);2797 set = try allocator.realloc(usize, set, set.len * 2);
2779 continue;2798 continue;
2799 }
2800 },
2801 posix.EFAULT => unreachable,
2802 posix.EINVAL => unreachable,
2803 posix.EPERM => return CpuCountError.PermissionDenied,
2804 posix.ESRCH => unreachable,
2805 else => return os.unexpectedErrorPosix(err),
2780 }2806 }
2781 },2807 }
2782 posix.EFAULT => unreachable,2808 },
2783 posix.EINVAL => unreachable,2809 else => @compileError("unsupported OS"),
2784 posix.EPERM => return CpuCountError.PermissionDenied,
2785 posix.ESRCH => unreachable,
2786 else => return os.unexpectedErrorPosix(err),
2787 }
2788 }2810 }
2789}2811}
27902812