| author | |
| committer | |
| log | 86d1cc8e2fffed9c93e41b28605d764e6b1749dc |
| tree | 0cf017f35e7f9800978c1d04f39562f5b31bccdf |
| parent | 9bd8b01650f9cf21e601117951711b21aa5fd216 |
4 files changed, 48 insertions(+), 0 deletions(-)
std/c/index.zig+1| ... | ... | @@ -58,6 +58,7 @@ pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias at |
| 58 | 58 | pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int; |
| 59 | 59 | pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int; |
| 60 | 60 | pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int; |
| 61 | pub extern "pthread" fn pthread_self() pthread_t; | |
| 61 | 62 | pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int; |
| 62 | 63 | |
| 63 | 64 | pub const pthread_t = *@OpaqueType(); |
std/os/index.zig+33| ... | ... | @@ -2516,6 +2516,10 @@ pub const Thread = struct { |
| 2516 | 2516 | data: Data, |
| 2517 | 2517 | |
| 2518 | 2518 | pub const use_pthreads = is_posix and builtin.link_libc; |
| 2519 | ||
| 2520 | /// An opaque type representing a kernel thread ID. | |
| 2521 | pub const Id = *@OpaqueType(); | |
| 2522 | ||
| 2519 | 2523 | pub const Data = if (use_pthreads) |
| 2520 | 2524 | struct { |
| 2521 | 2525 | handle: c.pthread_t, |
| ... | ... | @@ -2536,6 +2540,35 @@ pub const Thread = struct { |
| 2536 | 2540 | else => @compileError("Unsupported OS"), |
| 2537 | 2541 | }; |
| 2538 | 2542 | |
| 2543 | /// Returns the ID of the calling thread. | |
| 2544 | pub fn currentId() Thread.Id { | |
| 2545 | // TODO: As-is, this function is potentially expensive (making a | |
| 2546 | // syscall on every call). Once we have support for thread-local | |
| 2547 | // storage (https://github.com/ziglang/zig/issues/924), we could | |
| 2548 | // memoize it. | |
| 2549 | if (use_pthreads) { | |
| 2550 | return @ptrCast(Thread.Id, c.pthread_self()); | |
| 2551 | } else return switch (builtin.os) { | |
| 2552 | builtin.Os.linux => | |
| 2553 | @intToPtr(Thread.Id, @bitCast(u32, linux.getpid())), | |
| 2554 | builtin.Os.windows => | |
| 2555 | @ptrCast(Thread.Id, windows.GetCurrentThread()), | |
| 2556 | else => @compileError("Unsupported OS"), | |
| 2557 | }; | |
| 2558 | } | |
| 2559 | ||
| 2560 | /// Returns the ID of this thread object. | |
| 2561 | pub fn id(self: *const Thread) Thread.Id { | |
| 2562 | if (use_pthreads) { | |
| 2563 | return @ptrCast(Thread.Id, self.data.handle); | |
| 2564 | } else return switch (builtin.os) { | |
| 2565 | builtin.Os.linux => | |
| 2566 | @intToPtr(Thread.Id, @bitCast(u32, self.data.pid)), | |
| 2567 | builtin.Os.windows => @ptrCast(Thread.Id, self.data.handle), | |
| 2568 | else => @compileError("Unsupported OS"), | |
| 2569 | }; | |
| 2570 | } | |
| 2571 | ||
| 2539 | 2572 | pub fn wait(self: *const Thread) void { |
| 2540 | 2573 | if (use_pthreads) { |
| 2541 | 2574 | const err = c.pthread_join(self.data.handle, null); |
std/os/test.zig+12| ... | ... | @@ -34,6 +34,18 @@ test "access file" { |
| 34 | 34 | try os.deleteTree(a, "os_test_tmp"); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | fn testThreadIdFn(threadId: *?os.Thread.Id) void { | |
| 38 | threadId.* = os.Thread.currentId(); | |
| 39 | } | |
| 40 | ||
| 41 | test "std.os.Thread.currentId" { | |
| 42 | var threadCurrentId: ?os.Thread.Id = null; | |
| 43 | const thread = try os.spawnThread(&threadCurrentId, testThreadIdFn); | |
| 44 | const threadId = thread.id(); | |
| 45 | thread.wait(); | |
| 46 | assert(threadCurrentId == threadId); | |
| 47 | } | |
| 48 | ||
| 37 | 49 | test "spawn threads" { |
| 38 | 50 | var shared_ctx: i32 = 1; |
| 39 | 51 |
std/os/windows/kernel32.zig+2| ... | ... | @@ -63,6 +63,8 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out |
| 63 | 63 | |
| 64 | 64 | pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD; |
| 65 | 65 | |
| 66 | pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE; | |
| 67 | ||
| 66 | 68 | pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8; |
| 67 | 69 | |
| 68 | 70 | pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD; |