setName
Function parameters
Parameters
Type definitions in this namespace
Types
- SpawnConfig
- Configuration options for hints on how to spawn threads.
Spurious wakeups are possible and no precision of timing is guaranteed.
Functions
- sleep
- Spurious wakeups are possible and no precision of timing is guaranteed.
- getName
- On Windows, the result is encoded as [WTF-8](https://simonsapin.github.io/wtf-8/).
- getCurrentId
- Returns the platform ID of the callers thread.
- getCpuCount
- Returns the platforms view on the number of logical CPU cores available.
- spawn
- Spawns a new thread which executes `function` using `args` and returns a handle to the spawned thread.
- getHandle
- Returns the handle of this thread
- detach
- Release the obligation of the caller to call `join()` and have the thread clean up its own resources on completion.
- join
- Waits for the thread to complete, then deallocates any resources created on `spawn()`.
- yield
- Yields the current thread potentially allowing other threads to run.
Error sets in this namespace
Error Sets
= native_os != .windows and native_os != .wasi and builtin.link_libc
Values
- use_pthreads
- = native_os != .windows and native_os != .wasi and builtin.link_libc
- max_name_len
- = switch (native_os) { .linux => 15, .windows => 31, .macos, .ios, .watchos, .tvos, .visionos => 63, .netbsd => 31, .freebsd => 15, .openbsd => 23, .dragonfly => 1023, .solaris, .illumos => 31, // https://github.com/SerenityOS/serenity/blob/6b4c300353da49d3508b5442cf61da70bd04d757/Kernel/Tasks/Thread.h#L102 .serenity => 63, else => 0, }
- Handle
- Represents a kernel thread handle.
Source
Implementation
pub fn setName(self: Thread, name: []const u8) SetNameError!void {
if (name.len > max_name_len) return error.NameTooLong;
const name_with_terminator = blk: {
var name_buf: [max_name_len:0]u8 = undefined;
@memcpy(name_buf[0..name.len], name);
name_buf[name.len] = 0;
break :blk name_buf[0..name.len :0];
};
switch (native_os) {
.linux => if (use_pthreads) {
if (self.getHandle() == std.c.pthread_self()) {
// Set the name of the calling thread (no thread id required).
const err = try posix.prctl(.SET_NAME, .{@intFromPtr(name_with_terminator.ptr)});
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
else => |e| return posix.unexpectedErrno(e),
}
} else {
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
.RANGE => unreachable,
else => |e| return posix.unexpectedErrno(e),
}
}
} else {
var buf: [32]u8 = undefined;
const path = try std.fmt.bufPrint(&buf, "/proc/self/task/{d}/comm", .{self.getHandle()});
const file = try std.fs.cwd().openFile(path, .{ .mode = .write_only });
defer file.close();
try file.deprecatedWriter().writeAll(name);
return;
},
.windows => {
var buf: [max_name_len]u16 = undefined;
const len = try std.unicode.wtf8ToWtf16Le(&buf, name);
const byte_len = math.cast(c_ushort, len * 2) orelse return error.NameTooLong;
// Note: NT allocates its own copy, no use-after-free here.
const unicode_string = windows.UNICODE_STRING{
.Length = byte_len,
.MaximumLength = byte_len,
.Buffer = &buf,
};
switch (windows.ntdll.NtSetInformationThread(
self.getHandle(),
.ThreadNameInformation,
&unicode_string,
@sizeOf(windows.UNICODE_STRING),
)) {
.SUCCESS => return,
.NOT_IMPLEMENTED => return error.Unsupported,
else => |err| return windows.unexpectedStatus(err),
}
},
.macos, .ios, .watchos, .tvos, .visionos => if (use_pthreads) {
// There doesn't seem to be a way to set the name for an arbitrary thread, only the current one.
if (self.getHandle() != std.c.pthread_self()) return error.Unsupported;
const err = std.c.pthread_setname_np(name_with_terminator.ptr);
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
else => |e| return posix.unexpectedErrno(e),
}
},
.serenity => if (use_pthreads) {
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
.NAMETOOLONG => unreachable,
.SRCH => unreachable,
else => |e| return posix.unexpectedErrno(e),
}
},
.netbsd, .solaris, .illumos => if (use_pthreads) {
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr, null);
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
.INVAL => unreachable,
.SRCH => unreachable,
.NOMEM => unreachable,
else => |e| return posix.unexpectedErrno(e),
}
},
.freebsd, .openbsd => if (use_pthreads) {
// Use pthread_set_name_np for FreeBSD because pthread_setname_np is FreeBSD 12.2+ only.
// TODO maybe revisit this if depending on FreeBSD 12.2+ is acceptable because
// pthread_setname_np can return an error.
std.c.pthread_set_name_np(self.getHandle(), name_with_terminator.ptr);
return;
},
.dragonfly => if (use_pthreads) {
const err = std.c.pthread_setname_np(self.getHandle(), name_with_terminator.ptr);
switch (@as(posix.E, @enumFromInt(err))) {
.SUCCESS => return,
.INVAL => unreachable,
.FAULT => unreachable,
.NAMETOOLONG => unreachable, // already checked
.SRCH => unreachable,
else => |e| return posix.unexpectedErrno(e),
}
},
else => {},
}
return error.Unsupported;
}