std.Thread.cpuCount on Windows uses the PEB

rather than calling GetSystemInfo from kernel32.dll. Also remove
OutOfMemory from the error set.
This commit is contained in:
Andrew Kelley 2020-02-29 22:13:09 -05:00
parent d951e0402a
commit 6fcf6716be
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9

View File

@ -1,5 +1,5 @@
const builtin = @import("builtin");
const std = @import("std.zig");
const builtin = std.builtin;
const os = std.os;
const mem = std.mem;
const windows = std.os.windows;
@ -9,14 +9,14 @@ const assert = std.debug.assert;
pub const Thread = struct {
data: Data,
pub const use_pthreads = builtin.os.tag != .windows and builtin.link_libc;
pub const use_pthreads = std.Target.current.os.tag != .windows and builtin.link_libc;
/// Represents a kernel thread handle.
/// May be an integer or a pointer depending on the platform.
/// On Linux and POSIX, this is the same as Id.
pub const Handle = if (use_pthreads)
c.pthread_t
else switch (builtin.os.tag) {
else switch (std.Target.current.os.tag) {
.linux => i32,
.windows => windows.HANDLE,
else => void,
@ -25,7 +25,7 @@ pub const Thread = struct {
/// Represents a unique ID per thread.
/// May be an integer or pointer depending on the platform.
/// On Linux and POSIX, this is the same as Handle.
pub const Id = switch (builtin.os.tag) {
pub const Id = switch (std.Target.current.os.tag) {
.windows => windows.DWORD,
else => Handle,
};
@ -35,7 +35,7 @@ pub const Thread = struct {
handle: Thread.Handle,
memory: []align(mem.page_size) u8,
}
else switch (builtin.os.tag) {
else switch (std.Target.current.os.tag) {
.linux => struct {
handle: Thread.Handle,
memory: []align(mem.page_size) u8,
@ -55,7 +55,7 @@ pub const Thread = struct {
if (use_pthreads) {
return c.pthread_self();
} else
return switch (builtin.os.tag) {
return switch (std.Target.current.os.tag) {
.linux => os.linux.gettid(),
.windows => windows.kernel32.GetCurrentThreadId(),
else => @compileError("Unsupported OS"),
@ -83,7 +83,7 @@ pub const Thread = struct {
else => unreachable,
}
os.munmap(self.data.memory);
} else switch (builtin.os.tag) {
} else switch (std.Target.current.os.tag) {
.linux => {
while (true) {
const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst);
@ -150,7 +150,7 @@ pub const Thread = struct {
const Context = @TypeOf(context);
comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context);
if (builtin.os.tag == .windows) {
if (std.Target.current.os.tag == .windows) {
const WinThread = struct {
const OuterContext = struct {
thread: Thread,
@ -309,16 +309,16 @@ pub const Thread = struct {
os.EINVAL => unreachable,
else => return os.unexpectedErrno(@intCast(usize, err)),
}
} else if (builtin.os.tag == .linux) {
} else if (std.Target.current.os.tag == .linux) {
var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |
os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
os.CLONE_DETACHED;
var newtls: usize = undefined;
// This structure is only needed when targeting i386
var user_desc: if (builtin.arch == .i386) os.linux.user_desc else void = undefined;
var user_desc: if (std.Target.current.cpu.arch == .i386) os.linux.user_desc else void = undefined;
if (os.linux.tls.tls_image) |tls_img| {
if (builtin.arch == .i386) {
if (std.Target.current.cpu.arch == .i386) {
user_desc = os.linux.user_desc{
.entry_number = tls_img.gdt_entry_number,
.base_addr = os.linux.tls.copyTLS(mmap_addr + tls_start_offset),
@ -362,21 +362,18 @@ pub const Thread = struct {
}
pub const CpuCountError = error{
OutOfMemory,
PermissionDenied,
SystemResources,
Unexpected,
};
pub fn cpuCount() CpuCountError!usize {
if (builtin.os.tag == .linux) {
if (std.Target.current.os.tag == .linux) {
const cpu_set = try os.sched_getaffinity(0);
return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
}
if (builtin.os.tag == .windows) {
var system_info: windows.SYSTEM_INFO = undefined;
windows.kernel32.GetSystemInfo(&system_info);
return @intCast(usize, system_info.dwNumberOfProcessors);
if (std.Target.current.os.tag == .windows) {
return os.windows.peb().NumberOfProcessors;
}
var count: c_int = undefined;
var count_len: usize = @sizeOf(c_int);