aboutsummaryrefslogtreecommitdiff
path: root/std/os
diff options
context:
space:
mode:
Diffstat (limited to 'std/os')
-rw-r--r--std/os/index.zig33
-rw-r--r--std/os/test.zig12
-rw-r--r--std/os/windows/kernel32.zig2
3 files changed, 47 insertions, 0 deletions
diff --git a/std/os/index.zig b/std/os/index.zig
index 425a900a71..c946e13046 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -2516,6 +2516,10 @@ pub const Thread = struct {
data: Data,
pub const use_pthreads = is_posix and builtin.link_libc;
+
+ /// An opaque type representing a kernel thread ID.
+ pub const Id = *@OpaqueType();
+
pub const Data = if (use_pthreads)
struct {
handle: c.pthread_t,
@@ -2536,6 +2540,35 @@ pub const Thread = struct {
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 @ptrCast(Thread.Id, c.pthread_self());
+ } else return switch (builtin.os) {
+ builtin.Os.linux =>
+ @intToPtr(Thread.Id, @bitCast(u32, linux.getpid())),
+ builtin.Os.windows =>
+ @ptrCast(Thread.Id, windows.GetCurrentThread()),
+ else => @compileError("Unsupported OS"),
+ };
+ }
+
+ /// Returns the ID of this thread object.
+ pub fn id(self: *const Thread) Thread.Id {
+ if (use_pthreads) {
+ return @ptrCast(Thread.Id, self.data.handle);
+ } else return switch (builtin.os) {
+ builtin.Os.linux =>
+ @intToPtr(Thread.Id, @bitCast(u32, self.data.pid)),
+ builtin.Os.windows => @ptrCast(Thread.Id, self.data.handle),
+ else => @compileError("Unsupported OS"),
+ };
+ }
+
pub fn wait(self: *const Thread) void {
if (use_pthreads) {
const err = c.pthread_join(self.data.handle, null);
diff --git a/std/os/test.zig b/std/os/test.zig
index 9e795e8ad2..6ef38c6764 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 = null;
+ 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;