| ... | ... | @@ -23,6 +23,19 @@ pub const Condition = @import("Thread/Condition.zig"); |
| 23 | 23 | |
| 24 | 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 | 39 | pub const use_pthreads = target.os.tag != .windows and std.builtin.link_libc; |
| 27 | 40 | |
| 28 | 41 | const Thread = @This(); |
| ... | ... | @@ -37,15 +50,9 @@ else |
| 37 | 50 | |
| 38 | 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 | 53 | /// Represents a unique ID per thread. |
| 46 | 54 | /// May be an integer or pointer depending on the platform. |
| 47 | | /// On Linux and POSIX, this is the same as Handle. |
| 48 | | pub const Id = Impl.ThreadId; |
| 55 | pub const Id = u64; |
| 49 | 56 | |
| 50 | 57 | /// Returns the platform ID of the callers thread. |
| 51 | 58 | /// Attempts to use thread locals and avoid syscalls when possible. |
| ... | ... | @@ -120,8 +127,11 @@ pub fn spawn( |
| 120 | 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 | 134 | /// Retrns the handle of this thread |
| 124 | | /// On Linux and POSIX, this is the same as Id. |
| 125 | 135 | pub fn getHandle(self: Thread) Handle { |
| 126 | 136 | return self.impl.getHandle(); |
| 127 | 137 | } |
| ... | ... | @@ -137,7 +147,7 @@ pub fn join(self: Thread) void { |
| 137 | 147 | } |
| 138 | 148 | |
| 139 | 149 | /// State to synchronize detachment of spawner thread to spawned thread |
| 140 | | const Completion = Atomic(enum { |
| 150 | const Completion = Atomic(enum(u8) { |
| 141 | 151 | running, |
| 142 | 152 | detached, |
| 143 | 153 | completed, |
| ... | ... | @@ -199,9 +209,8 @@ const WindowsThreadImpl = struct { |
| 199 | 209 | const windows = os.windows; |
| 200 | 210 | |
| 201 | 211 | pub const ThreadHandle = windows.HANDLE; |
| 202 | | pub const ThreadId = windows.DWORD; |
| 203 | 212 | |
| 204 | | fn getCurrentId() ThreadId { |
| 213 | fn getCurrentId() u64 { |
| 205 | 214 | return windows.kernel.GetCurrentThreadId(); |
| 206 | 215 | } |
| 207 | 216 | |
| ... | ... | @@ -291,10 +300,37 @@ const PosixThreadImpl = struct { |
| 291 | 300 | const c = std.c; |
| 292 | 301 | |
| 293 | 302 | pub const ThreadHandle = c.pthread_t; |
| 294 | | pub const ThreadId = ThreadHandle; |
| 295 | 303 | |
| 296 | | fn getCurrentId() ThreadId { |
| 297 | | return c.pthread_self(); |
| 304 | fn getCurrentId() Id { |
| 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 | 336 | fn getCpuCount() !usize { |
| ... | ... | @@ -397,11 +433,10 @@ const LinuxThreadImpl = struct { |
| 397 | 433 | const linux = os.linux; |
| 398 | 434 | |
| 399 | 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 | 440 | return tls_thread_id orelse { |
| 406 | 441 | const tid = linux.gettid(); |
| 407 | 442 | tls_thread_id = tid; |