diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-08-06 16:12:37 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-08-06 16:12:37 -0400 |
| commit | 647fd0f4f1f99bc5bb7783cfc293e026974207c5 (patch) | |
| tree | 267afddfbebed33a4742246e6a17768acc8fa663 /std | |
| parent | 72bac72338af64a73668721cd035dfdf1ff2badb (diff) | |
| parent | 7a2401ef1eca3446279469b092e6f9c9653e38f8 (diff) | |
| download | zig-647fd0f4f1f99bc5bb7783cfc293e026974207c5.tar.gz zig-647fd0f4f1f99bc5bb7783cfc293e026974207c5.zip | |
Merge branch 'threadid' of https://github.com/mdsteele/zig into mdsteele-threadid
Diffstat (limited to 'std')
| -rw-r--r-- | std/c/index.zig | 1 | ||||
| -rw-r--r-- | std/os/index.zig | 42 | ||||
| -rw-r--r-- | std/os/test.zig | 12 | ||||
| -rw-r--r-- | std/os/windows/kernel32.zig | 2 |
4 files changed, 51 insertions, 6 deletions
diff --git a/std/c/index.zig b/std/c/index.zig index 7de8634d07..738b2f9c05 100644 --- a/std/c/index.zig +++ b/std/c/index.zig @@ -58,6 +58,7 @@ pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias at pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int; pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int; pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int; +pub extern "pthread" fn pthread_self() pthread_t; pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int; pub const pthread_t = *@OpaqueType(); diff --git a/std/os/index.zig b/std/os/index.zig index 425a900a71..a35f244e38 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -2516,26 +2516,56 @@ pub const Thread = struct { data: Data, pub const use_pthreads = is_posix and builtin.link_libc; + + /// An type representing a kernel thread ID. + pub const Id = if (use_pthreads) + c.pthread_t + else switch (builtin.os) { + builtin.Os.linux => i32, + builtin.Os.windows => windows.HANDLE, + else => @compileError("Unsupported OS"), + }; + pub const Data = if (use_pthreads) struct { - handle: c.pthread_t, + handle: Thread.Id, stack_addr: usize, stack_len: usize, } else switch (builtin.os) { builtin.Os.linux => struct { - pid: i32, + handle: Thread.Id, stack_addr: usize, stack_len: usize, }, builtin.Os.windows => struct { - handle: windows.HANDLE, + handle: Thread.Id, alloc_start: *c_void, heap_handle: windows.HANDLE, }, else => @compileError("Unsupported OS"), }; + /// Returns the ID of the calling thread. + pub fn currentId() Thread.Id { + // TODO: As-is, this function is potentially expensive (making a + // syscall on every call). Once we have support for thread-local + // storage (https://github.com/ziglang/zig/issues/924), we could + // memoize it. + if (use_pthreads) { + return c.pthread_self(); + } else return switch (builtin.os) { + builtin.Os.linux => linux.getpid(), + builtin.Os.windows => windows.GetCurrentThread(), + else => @compileError("Unsupported OS"), + }; + } + + /// Returns the ID of this thread. + pub fn id(self: *const Thread) Thread.Id { + return self.data.handle; + } + pub fn wait(self: *const Thread) void { if (use_pthreads) { const err = c.pthread_join(self.data.handle, null); @@ -2550,9 +2580,9 @@ pub const Thread = struct { } else switch (builtin.os) { builtin.Os.linux => { while (true) { - const pid_value = @atomicLoad(i32, &self.data.pid, builtin.AtomicOrder.SeqCst); + const pid_value = @atomicLoad(i32, &self.data.handle, builtin.AtomicOrder.SeqCst); if (pid_value == 0) break; - const rc = linux.futex_wait(@ptrToInt(&self.data.pid), linux.FUTEX_WAIT, pid_value, null); + const rc = linux.futex_wait(@ptrToInt(&self.data.handle), linux.FUTEX_WAIT, pid_value, null); switch (linux.getErrno(rc)) { 0 => continue, posix.EINTR => continue, @@ -2734,7 +2764,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread // use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly const flags = posix.CLONE_VM | posix.CLONE_FS | posix.CLONE_FILES | posix.CLONE_SIGHAND | posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID | posix.CLONE_DETACHED; const newtls: usize = 0; - const rc = posix.clone(MainFuncs.linuxThreadMain, stack_end, flags, arg, &thread_ptr.data.pid, newtls, &thread_ptr.data.pid); + const rc = posix.clone(MainFuncs.linuxThreadMain, stack_end, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle); const err = posix.getErrno(rc); switch (err) { 0 => return thread_ptr, diff --git a/std/os/test.zig b/std/os/test.zig index 9e795e8ad2..e983935b73 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -34,6 +34,18 @@ test "access file" { try os.deleteTree(a, "os_test_tmp"); } +fn testThreadIdFn(threadId: *os.Thread.Id) void { + threadId.* = os.Thread.currentId(); +} + +test "std.os.Thread.currentId" { + var threadCurrentId: os.Thread.Id = undefined; + const thread = try os.spawnThread(&threadCurrentId, testThreadIdFn); + const threadId = thread.id(); + thread.wait(); + assert(threadCurrentId == threadId); +} + test "spawn threads" { var shared_ctx: i32 = 1; diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index fa3473ad05..a28179f4eb 100644 --- a/std/os/windows/kernel32.zig +++ b/std/os/windows/kernel32.zig @@ -63,6 +63,8 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD; +pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE; + pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8; pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD; |
