From 4616af0ca459358ffa09ba27f9daa8527a38fd35 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 25 Feb 2020 01:52:27 -0500 Subject: introduce operating system version ranges as part of the target * re-introduce `std.build.Target` which is distinct from `std.Target`. `std.build.Target` wraps `std.Target` so that it can be annotated as "the native target" or an explicitly specified target. * `std.Target.Os` is moved to `std.Target.Os.Tag`. The former is now a struct which has the tag as well as version range information. * `std.elf` gains some more ELF header constants. * `std.Target.parse` gains the ability to parse operating system version ranges as well as glibc version. * Added `std.Target.isGnuLibC()`. * self-hosted dynamic linker detection and glibc version detection. This also adds the improved logic using `/usr/bin/env` rather than invoking the system C compiler to find the dynamic linker when zig is statically linked. Related: #2084 Note: this `/usr/bin/env` code is work-in-progress. * `-target-glibc` CLI option is removed in favor of the new `-target` syntax. Example: `-target x86_64-linux-gnu.2.27` closes #1907 --- lib/std/thread.zig | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'lib/std/thread.zig') diff --git a/lib/std/thread.zig b/lib/std/thread.zig index fcc71ae5a5..55db9d1733 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -9,14 +9,14 @@ const assert = std.debug.assert; pub const Thread = struct { data: Data, - pub const use_pthreads = builtin.os != .windows and builtin.link_libc; + pub const use_pthreads = builtin.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) { + else switch (builtin.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) { + pub const Id = switch (builtin.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) { + else switch (builtin.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) { + return switch (builtin.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) { + } else switch (builtin.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 == builtin.Os.windows) { + if (builtin.os.tag == .windows) { const WinThread = struct { const OuterContext = struct { thread: Thread, @@ -309,7 +309,7 @@ pub const Thread = struct { os.EINVAL => unreachable, else => return os.unexpectedErrno(@intCast(usize, err)), } - } else if (builtin.os == .linux) { + } else if (builtin.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; @@ -369,11 +369,11 @@ pub const Thread = struct { }; pub fn cpuCount() CpuCountError!usize { - if (builtin.os == .linux) { + if (builtin.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 == .windows) { + if (builtin.os.tag == .windows) { var system_info: windows.SYSTEM_INFO = undefined; windows.kernel32.GetSystemInfo(&system_info); return @intCast(usize, system_info.dwNumberOfProcessors); -- cgit v1.2.3 From 845af5c55208753dc355fad734a8c4893338f8f6 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 29 Feb 2020 23:11:36 +0100 Subject: Handle one more error --- lib/std/thread.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/std/thread.zig') diff --git a/lib/std/thread.zig b/lib/std/thread.zig index 55db9d1733..de9d580af7 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -382,7 +382,7 @@ pub const Thread = struct { var count_len: usize = @sizeOf(c_int); const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu"; os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) { - error.NameTooLong => unreachable, + error.NameTooLong, error.UnknownName => unreachable, else => |e| return e, }; return @intCast(usize, count); -- cgit v1.2.3 From 6fcf6716be3021d99d4972e8ca9b2139e1f8f40b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 29 Feb 2020 22:13:09 -0500 Subject: std.Thread.cpuCount on Windows uses the PEB rather than calling GetSystemInfo from kernel32.dll. Also remove OutOfMemory from the error set. --- lib/std/thread.zig | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'lib/std/thread.zig') diff --git a/lib/std/thread.zig b/lib/std/thread.zig index de9d580af7..b2f8a44a47 100644 --- a/lib/std/thread.zig +++ b/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); -- cgit v1.2.3