authorgravatar for mdsteele@alum.mit.eduMatthew D. Steele <mdsteele@alum.mit.edu> 2018-08-02 17:44:20-04:00
committergravatar for mdsteele@alum.mit.eduMatthew D. Steele <mdsteele@alum.mit.edu> 2018-08-03 21:36:04-04:00
log86d1cc8e2fffed9c93e41b28605d764e6b1749dc
tree0cf017f35e7f9800978c1d04f39562f5b31bccdf
parent9bd8b01650f9cf21e601117951711b21aa5fd216

Add thread ID support to std.os.Thread (fixes #1316)


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
5858pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
5959pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
6060pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
61pub extern "pthread" fn pthread_self() pthread_t;
6162pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
6263
6364pub const pthread_t = *@OpaqueType();
std/os/index.zig+33
......@@ -2516,6 +2516,10 @@ pub const Thread = struct {
25162516 data: Data,
25172517
25182518 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
25192523 pub const Data = if (use_pthreads)
25202524 struct {
25212525 handle: c.pthread_t,
......@@ -2536,6 +2540,35 @@ pub const Thread = struct {
25362540 else => @compileError("Unsupported OS"),
25372541 };
25382542
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
25392572 pub fn wait(self: *const Thread) void {
25402573 if (use_pthreads) {
25412574 const err = c.pthread_join(self.data.handle, null);
std/os/test.zig+12
......@@ -34,6 +34,18 @@ test "access file" {
3434 try os.deleteTree(a, "os_test_tmp");
3535}
3636
37fn testThreadIdFn(threadId: *?os.Thread.Id) void {
38 threadId.* = os.Thread.currentId();
39}
40
41test "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
3749test "spawn threads" {
3850 var shared_ctx: i32 = 1;
3951
std/os/windows/kernel32.zig+2
......@@ -63,6 +63,8 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out
6363
6464pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
6565
66pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;
67
6668pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
6769
6870pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;