darwin: add thread_act_t wrapper and helpers

This commit is contained in:
Jakub Konka 2022-12-13 12:53:10 +01:00
parent 2efd0eb884
commit f505cb96f4
2 changed files with 56 additions and 4 deletions

View File

@ -603,6 +603,9 @@ pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t;
pub const THREAD_BASIC_INFO = 3;
pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);
pub const THREAD_IDENTIFIER_INFO = 4;
pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_identifier_info) / @sizeOf(natural_t);
pub const thread_flavor_t = natural_t;
pub const thread_info_t = *integer_t;
pub const time_value_t = time_value;
@ -634,6 +637,17 @@ pub const thread_basic_info = extern struct {
sleep_time: integer_t,
};
pub const thread_identifier_info = extern struct {
/// System-wide unique 64-bit thread id
thread_id: u64,
/// Handle to be used by libproc
thread_handle: u64,
/// libdispatch queue address
dispatch_qaddr: u64,
};
/// Cachability
pub const MATTR_CACHE = 1;
/// Migrability

View File

@ -17,11 +17,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
Unexpected,
};
pub const MachTask = struct {
pub const MachTask = extern struct {
port: std.c.mach_port_name_t,
pub fn isValid(self: MachTask) bool {
return self.port != 0;
return self.port != std.c.TASK_NULL;
}
pub fn allocatePort(self: MachTask, right: std.c.MACH_PORT_RIGHT) MachError!MachTask {
@ -439,11 +439,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
}
pub fn getThreads(task: MachTask) MachError![]std.c.mach_port_t {
pub fn getThreads(task: MachTask) MachError![]ThreadId {
var thread_list: std.c.mach_port_array_t = undefined;
var thread_count: std.c.mach_msg_type_number_t = undefined;
switch (std.c.getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) {
.SUCCESS => return thread_list[0..thread_count],
.SUCCESS => return @ptrCast([*]ThreadId, thread_list)[0..thread_count],
else => |err| {
log.err("task_threads kernel call failed with error code: {s}", .{@tagName(err)});
return error.Unexpected;
@ -452,6 +452,44 @@ const mach_task = if (builtin.target.isDarwin()) struct {
}
};
pub const ThreadId = extern struct {
id: std.c.thread_act_t,
pub fn getBasicInfo(thread_id: ThreadId) MachError!std.c.thread_basic_info {
var info: std.c.thread_basic_info = undefined;
var count = std.c.THREAD_BASIC_INFO_COUNT;
switch (std.c.getKernError(std.c.thread_info(
thread_id.id,
std.c.THREAD_BASIC_INFO,
@ptrCast(std.c.thread_info_t, &info),
&count,
))) {
.SUCCESS => return info,
else => |err| {
log.err("thread_info kernel call failed with error code: {s}", .{@tagName(err)});
return error.Unexpected;
},
}
}
pub fn getIdentifierInfo(thread_id: ThreadId) MachError!std.c.thread_identifier_info {
var info: std.c.thread_identifier_info = undefined;
var count = std.c.THREAD_IDENTIFIER_INFO_COUNT;
switch (std.c.getKernError(std.c.thread_info(
thread_id.id,
std.c.THREAD_IDENTIFIER_INFO,
@ptrCast(std.c.thread_info_t, &info),
&count,
))) {
.SUCCESS => return info,
else => |err| {
log.err("thread_info kernel call failed with error code: {s}", .{@tagName(err)});
return error.Unexpected;
},
}
}
};
pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask {
var port: std.c.mach_port_name_t = undefined;
switch (std.c.getKernError(std.c.task_for_pid(std.c.mach_task_self(), pid, &port))) {