authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-13 12:53:10+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-13 12:53:10+01:00
logf505cb96f44e1739e3616fe2fb64bb84c44067e8
tree62a00156f4109c21b90d21209196bfbb14aca9a1
parent2efd0eb884d69c967f8b0c7066d62a8b656f1fda

darwin: add thread_act_t wrapper and helpers


2 files changed, 56 insertions(+), 4 deletions(-)

lib/std/c/darwin.zig+14
...@@ -603,6 +603,9 @@ pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t;...@@ -603,6 +603,9 @@ pub extern "c" fn thread_resume(thread: thread_act_t) kern_return_t;
603pub const THREAD_BASIC_INFO = 3;603pub const THREAD_BASIC_INFO = 3;
604pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);604pub const THREAD_BASIC_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_basic_info) / @sizeOf(natural_t);
605605
606pub const THREAD_IDENTIFIER_INFO = 4;
607pub const THREAD_IDENTIFIER_INFO_COUNT: mach_msg_type_number_t = @sizeOf(thread_identifier_info) / @sizeOf(natural_t);
608
606pub const thread_flavor_t = natural_t;609pub const thread_flavor_t = natural_t;
607pub const thread_info_t = *integer_t;610pub const thread_info_t = *integer_t;
608pub const time_value_t = time_value;611pub const time_value_t = time_value;
...@@ -634,6 +637,17 @@ pub const thread_basic_info = extern struct {...@@ -634,6 +637,17 @@ pub const thread_basic_info = extern struct {
634 sleep_time: integer_t,637 sleep_time: integer_t,
635};638};
636639
640pub const thread_identifier_info = extern struct {
641 /// System-wide unique 64-bit thread id
642 thread_id: u64,
643
644 /// Handle to be used by libproc
645 thread_handle: u64,
646
647 /// libdispatch queue address
648 dispatch_qaddr: u64,
649};
650
637/// Cachability651/// Cachability
638pub const MATTR_CACHE = 1;652pub const MATTR_CACHE = 1;
639/// Migrability653/// Migrability
lib/std/os/darwin.zig+42-4
...@@ -17,11 +17,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {...@@ -17,11 +17,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
17 Unexpected,17 Unexpected,
18 };18 };
1919
20 pub const MachTask = struct {20 pub const MachTask = extern struct {
21 port: std.c.mach_port_name_t,21 port: std.c.mach_port_name_t,
2222
23 pub fn isValid(self: MachTask) bool {23 pub fn isValid(self: MachTask) bool {
24 return self.port != 0;24 return self.port != std.c.TASK_NULL;
25 }25 }
2626
27 pub fn allocatePort(self: MachTask, right: std.c.MACH_PORT_RIGHT) MachError!MachTask {27 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 {...@@ -439,11 +439,11 @@ const mach_task = if (builtin.target.isDarwin()) struct {
439 }439 }
440 }440 }
441441
442 pub fn getThreads(task: MachTask) MachError![]std.c.mach_port_t {442 pub fn getThreads(task: MachTask) MachError![]ThreadId {
443 var thread_list: std.c.mach_port_array_t = undefined;443 var thread_list: std.c.mach_port_array_t = undefined;
444 var thread_count: std.c.mach_msg_type_number_t = undefined;444 var thread_count: std.c.mach_msg_type_number_t = undefined;
445 switch (std.c.getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) {445 switch (std.c.getKernError(std.c.task_threads(task.port, &thread_list, &thread_count))) {
446 .SUCCESS => return thread_list[0..thread_count],446 .SUCCESS => return @ptrCast([*]ThreadId, thread_list)[0..thread_count],
447 else => |err| {447 else => |err| {
448 log.err("task_threads kernel call failed with error code: {s}", .{@tagName(err)});448 log.err("task_threads kernel call failed with error code: {s}", .{@tagName(err)});
449 return error.Unexpected;449 return error.Unexpected;
...@@ -452,6 +452,44 @@ const mach_task = if (builtin.target.isDarwin()) struct {...@@ -452,6 +452,44 @@ const mach_task = if (builtin.target.isDarwin()) struct {
452 }452 }
453 };453 };
454454
455 pub const ThreadId = extern struct {
456 id: std.c.thread_act_t,
457
458 pub fn getBasicInfo(thread_id: ThreadId) MachError!std.c.thread_basic_info {
459 var info: std.c.thread_basic_info = undefined;
460 var count = std.c.THREAD_BASIC_INFO_COUNT;
461 switch (std.c.getKernError(std.c.thread_info(
462 thread_id.id,
463 std.c.THREAD_BASIC_INFO,
464 @ptrCast(std.c.thread_info_t, &info),
465 &count,
466 ))) {
467 .SUCCESS => return info,
468 else => |err| {
469 log.err("thread_info kernel call failed with error code: {s}", .{@tagName(err)});
470 return error.Unexpected;
471 },
472 }
473 }
474
475 pub fn getIdentifierInfo(thread_id: ThreadId) MachError!std.c.thread_identifier_info {
476 var info: std.c.thread_identifier_info = undefined;
477 var count = std.c.THREAD_IDENTIFIER_INFO_COUNT;
478 switch (std.c.getKernError(std.c.thread_info(
479 thread_id.id,
480 std.c.THREAD_IDENTIFIER_INFO,
481 @ptrCast(std.c.thread_info_t, &info),
482 &count,
483 ))) {
484 .SUCCESS => return info,
485 else => |err| {
486 log.err("thread_info kernel call failed with error code: {s}", .{@tagName(err)});
487 return error.Unexpected;
488 },
489 }
490 }
491 };
492
455 pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask {493 pub fn machTaskForPid(pid: std.os.pid_t) MachError!MachTask {
456 var port: std.c.mach_port_name_t = undefined;494 var port: std.c.mach_port_name_t = undefined;
457 switch (std.c.getKernError(std.c.task_for_pid(std.c.mach_task_self(), pid, &port))) {495 switch (std.c.getKernError(std.c.task_for_pid(std.c.mach_task_self(), pid, &port))) {