| ... | @@ -2756,35 +2756,57 @@ pub const CpuCountError = error{ | ... | @@ -2756,35 +2756,57 @@ pub const CpuCountError = error{ |
| 2756 | }; | 2756 | }; |
| 2757 | | 2757 | |
| 2758 | pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { | 2758 | pub 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(); |
| 2761 | | 2780 | |
| 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); |
| 2764 | | 2783 | |
| 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 | } |
| 2790 | | 2812 | |