authorgravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2021-06-20 07:38:26-05:00
committergravatar for kbutcher6200@gmail.comkprotty <kbutcher6200@gmail.com> 2021-06-30 21:49:00-05:00
log6ff64895cf0c8f331959d34dec5f4fa84e7c6365
tree401939c9bf80f1847a5872a71c58959482c1dac9
parent235fcc5ba632ced7e972e1c8b133418c17cd7ab7

std.Thread: add tests + getCurrentId() returns ints when possible


1 files changed, 52 insertions(+), 17 deletions(-)

lib/std/Thread.zig+52-17
...@@ -23,6 +23,19 @@ pub const Condition = @import("Thread/Condition.zig");...@@ -23,6 +23,19 @@ pub const Condition = @import("Thread/Condition.zig");
2323
24pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint");24pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint");
2525
26test "std.Thread" {
27 if (!builtin.single_threaded) {
28 // Doesn't use testing.refAllDecls() since that would pull in the compileError spinLoopHint.
29 _ = AutoResetEvent;
30 _ = Futex;
31 _ = ResetEvent;
32 _ = StaticResetEvent;
33 _ = Mutex;
34 _ = Semaphore;
35 _ = Condition;
36 }
37}
38
26pub const use_pthreads = target.os.tag != .windows and std.builtin.link_libc;39pub const use_pthreads = target.os.tag != .windows and std.builtin.link_libc;
2740
28const Thread = @This();41const Thread = @This();
...@@ -37,15 +50,9 @@ else...@@ -37,15 +50,9 @@ else
3750
38impl: Impl,51impl: Impl,
3952
40/// Represents a kernel thread handle.
41/// May be an integer or a pointer depending on the platform.
42/// On Linux and POSIX, this is the same as Id.
43pub const Handle = Impl.ThreadHandle;
44
45/// Represents a unique ID per thread.53/// Represents a unique ID per thread.
46/// May be an integer or pointer depending on the platform.54/// May be an integer or pointer depending on the platform.
47/// On Linux and POSIX, this is the same as Handle.55pub const Id = u64;
48pub const Id = Impl.ThreadId;
4956
50/// Returns the platform ID of the callers thread.57/// Returns the platform ID of the callers thread.
51/// Attempts to use thread locals and avoid syscalls when possible.58/// Attempts to use thread locals and avoid syscalls when possible.
...@@ -120,8 +127,11 @@ pub fn spawn(...@@ -120,8 +127,11 @@ pub fn spawn(
120 return .{ .impl = impl };127 return .{ .impl = impl };
121}128}
122129
130/// Represents a kernel thread handle.
131/// May be an integer or a pointer depending on the platform.
132pub const Handle = Impl.ThreadHandle;
133
123/// Retrns the handle of this thread134/// Retrns the handle of this thread
124/// On Linux and POSIX, this is the same as Id.
125pub fn getHandle(self: Thread) Handle {135pub fn getHandle(self: Thread) Handle {
126 return self.impl.getHandle();136 return self.impl.getHandle();
127}137}
...@@ -137,7 +147,7 @@ pub fn join(self: Thread) void {...@@ -137,7 +147,7 @@ pub fn join(self: Thread) void {
137}147}
138148
139/// State to synchronize detachment of spawner thread to spawned thread149/// State to synchronize detachment of spawner thread to spawned thread
140const Completion = Atomic(enum {150const Completion = Atomic(enum(u8) {
141 running,151 running,
142 detached,152 detached,
143 completed,153 completed,
...@@ -199,9 +209,8 @@ const WindowsThreadImpl = struct {...@@ -199,9 +209,8 @@ const WindowsThreadImpl = struct {
199 const windows = os.windows;209 const windows = os.windows;
200210
201 pub const ThreadHandle = windows.HANDLE;211 pub const ThreadHandle = windows.HANDLE;
202 pub const ThreadId = windows.DWORD;
203212
204 fn getCurrentId() ThreadId {213 fn getCurrentId() u64 {
205 return windows.kernel.GetCurrentThreadId();214 return windows.kernel.GetCurrentThreadId();
206 }215 }
207216
...@@ -291,10 +300,37 @@ const PosixThreadImpl = struct {...@@ -291,10 +300,37 @@ const PosixThreadImpl = struct {
291 const c = std.c;300 const c = std.c;
292301
293 pub const ThreadHandle = c.pthread_t;302 pub const ThreadHandle = c.pthread_t;
294 pub const ThreadId = ThreadHandle;
295303
296 fn getCurrentId() ThreadId {304 fn getCurrentId() Id {
297 return c.pthread_self();305 switch (target.os.tag) {
306 .linux => {
307 return LinuxThreadImpl.getCurrentId();
308 },
309 .macos, .ios, .watchos, .tvos => {
310 var thread_id: u64 = undefined;
311 // Pass thread=null to get the current thread ID.
312 assert(c.pthread_threadid_np(null, &thread_id) == 0);
313 return thread_id;
314 },
315 .dragonfly => {
316 return @bitCast(u32, c.lwp_gettid());
317 },
318 .netbsd => {
319 return @bitCast(u32, c._lwp_self());
320 },
321 .freebsd => {
322 return @bitCast(u32, c.pthread_getthreadid_np());
323 },
324 .openbsd => {
325 return @bitCast(u32, c.getthrid());
326 },
327 .haiku => {
328 return @bitCast(u32, c.find_thread(null));
329 },
330 else => {
331 return @ptrToInt(c.pthread_self());
332 },
333 }
298 }334 }
299335
300 fn getCpuCount() !usize {336 fn getCpuCount() !usize {
...@@ -397,11 +433,10 @@ const LinuxThreadImpl = struct {...@@ -397,11 +433,10 @@ const LinuxThreadImpl = struct {
397 const linux = os.linux;433 const linux = os.linux;
398 434
399 pub const ThreadHandle = i32;435 pub const ThreadHandle = i32;
400 pub const ThreadId = ThreadHandle;
401436
402 threadlocal var tls_thread_id: ?ThreadId = null;437 threadlocal var tls_thread_id: ?Id = null;
403438
404 fn getCurrentId() ThreadId {439 fn getCurrentId() Id {
405 return tls_thread_id orelse {440 return tls_thread_id orelse {
406 const tid = linux.gettid();441 const tid = linux.gettid();
407 tls_thread_id = tid;442 tls_thread_id = tid;