Commit 6fcf6716be

Andrew Kelley <andrew@ziglang.org>
2020-03-01 04:13:09
std.Thread.cpuCount on Windows uses the PEB
rather than calling GetSystemInfo from kernel32.dll. Also remove OutOfMemory from the error set.
1 parent d951e04
Changed files (1)
lib
lib/std/thread.zig
@@ -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);