| ... | @@ -23,6 +23,19 @@ pub const Condition = @import("Thread/Condition.zig"); | ... | @@ -23,6 +23,19 @@ pub const Condition = @import("Thread/Condition.zig"); |
| 23 | | 23 | |
| 24 | pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint"); | 24 | pub const spinLoopHint = @compileError("deprecated: use std.atomic.spinLoopHint"); |
| 25 | | 25 | |
| | 26 | test "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 | |
| 26 | pub const use_pthreads = target.os.tag != .windows and std.builtin.link_libc; | 39 | pub const use_pthreads = target.os.tag != .windows and std.builtin.link_libc; |
| 27 | | 40 | |
| 28 | const Thread = @This(); | 41 | const Thread = @This(); |
| ... | @@ -37,15 +50,9 @@ else | ... | @@ -37,15 +50,9 @@ else |
| 37 | | 50 | |
| 38 | impl: Impl, | 51 | impl: Impl, |
| 39 | | 52 | |
| 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. | | |
| 43 | pub 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. | 55 | pub const Id = u64; |
| 48 | pub const Id = Impl.ThreadId; | | |
| 49 | | 56 | |
| 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 | } |
| 122 | | 129 | |
| | 130 | /// Represents a kernel thread handle. |
| | 131 | /// May be an integer or a pointer depending on the platform. |
| | 132 | pub const Handle = Impl.ThreadHandle; |
| | 133 | |
| 123 | /// Retrns the handle of this thread | 134 | /// Retrns the handle of this thread |
| 124 | /// On Linux and POSIX, this is the same as Id. | | |
| 125 | pub fn getHandle(self: Thread) Handle { | 135 | pub 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 | } |
| 138 | | 148 | |
| 139 | /// State to synchronize detachment of spawner thread to spawned thread | 149 | /// State to synchronize detachment of spawner thread to spawned thread |
| 140 | const Completion = Atomic(enum { | 150 | const 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; |
| 200 | | 210 | |
| 201 | pub const ThreadHandle = windows.HANDLE; | 211 | pub const ThreadHandle = windows.HANDLE; |
| 202 | pub const ThreadId = windows.DWORD; | | |
| 203 | | 212 | |
| 204 | fn getCurrentId() ThreadId { | 213 | fn getCurrentId() u64 { |
| 205 | return windows.kernel.GetCurrentThreadId(); | 214 | return windows.kernel.GetCurrentThreadId(); |
| 206 | } | 215 | } |
| 207 | | 216 | |
| ... | @@ -291,10 +300,37 @@ const PosixThreadImpl = struct { | ... | @@ -291,10 +300,37 @@ const PosixThreadImpl = struct { |
| 291 | const c = std.c; | 300 | const c = std.c; |
| 292 | | 301 | |
| 293 | pub const ThreadHandle = c.pthread_t; | 302 | pub const ThreadHandle = c.pthread_t; |
| 294 | pub const ThreadId = ThreadHandle; | | |
| 295 | | 303 | |
| 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 | } |
| 299 | | 335 | |
| 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; | | |
| 401 | | 436 | |
| 402 | threadlocal var tls_thread_id: ?ThreadId = null; | 437 | threadlocal var tls_thread_id: ?Id = null; |
| 403 | | 438 | |
| 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; |