Skip to content

Commit 86d1cc8

Browse files
committed
Add thread ID support to std.os.Thread (fixes #1316)
1 parent 9bd8b01 commit 86d1cc8

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

std/c/index.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias at
5858
pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
5959
pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
6060
pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
61+
pub extern "pthread" fn pthread_self() pthread_t;
6162
pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
6263

6364
pub const pthread_t = *@OpaqueType();

std/os/index.zig

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ test "access file" {
3434
try os.deleteTree(a, "os_test_tmp");
3535
}
3636

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+
3749
test "spawn threads" {
3850
var shared_ctx: i32 = 1;
3951

std/os/windows/kernel32.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out
6363

6464
pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
6565

66+
pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;
67+
6668
pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
6769

6870
pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;

0 commit comments

Comments
 (0)