-
Notifications
You must be signed in to change notification settings - Fork 129
[DRAFT] ProcessID, Signal, SignalSet, TaskInfo, ResourceUsageInfo #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
ad80d0f
0ebaa29
544fc8a
881a8ad
0c32e4e
c96a3e6
a051d71
153e5d3
e8b5ab4
9edaf16
5bc82a4
9830717
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
|
|
||
| extension ProcessID { | ||
| public struct ResourceUsageInfo: RawRepresentable/*, Hashable, Codable*/ { | ||
| /// The raw C process id. | ||
| @_alwaysEmitIntoClient | ||
| public let rawValue: CInterop.RUsageInfo | ||
|
|
||
| /// Creates a strongly-typed process id from a raw C pid | ||
| @_alwaysEmitIntoClient | ||
| public init(rawValue: CInterop.RUsageInfo) { self.rawValue = rawValue } | ||
|
|
||
| fileprivate init(_ rawValue: CInterop.RUsageInfo) { | ||
| self.init(rawValue: rawValue) | ||
| } | ||
|
|
||
| fileprivate static var blank: ResourceUsageInfo { | ||
| ResourceUsageInfo(rusage_info_current()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // FIXME(DO NOT MERGE): system_foo wrappers for these and mocking | ||
| import CSystem | ||
| extension ProcessID { | ||
| public func getResourceUsageInfo() throws -> ResourceUsageInfo { | ||
| var current = ResourceUsageInfo.blank | ||
| try withUnsafeMutablePointer(to: ¤t) { | ||
| try $0.withMemoryRebound(to: rusage_info_t?.self, capacity: 1) { | ||
| guard 0 == proc_pid_rusage(self.rawValue, RUSAGE_INFO_CURRENT, $0) else { | ||
| throw Errno(rawValue: errno) | ||
| } | ||
| } | ||
| } | ||
| return current | ||
| } | ||
| } | ||
|
|
||
| // FIXME: docs or comments, the headers have none... | ||
| // FIXME: names | ||
| extension ProcessID.ResourceUsageInfo { | ||
| // FIXME: UUID proper type | ||
| public typealias UUID = ( | ||
| UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, | ||
| UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) | ||
|
|
||
| /// `ri_uuid`: TBD | ||
| public var uuid: UUID { rawValue.ri_uuid } | ||
|
|
||
| /// `ri_user_time`: TBD | ||
| public var userTime: UInt64 { rawValue.ri_user_time } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should specify units for all these dimensioned quantities, ideally at the type system level. Should these time intervals return whatever we end up using for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately the headers are not clear what even is here. It's like that |
||
|
|
||
| /// `ri_system_time`: TBD | ||
| public var systemTime: UInt64 { rawValue.ri_system_time } | ||
|
|
||
| /// `ri_pkg_idle_wkups`: TBD | ||
| public var pkgIdleWakeups: UInt64 { rawValue.ri_pkg_idle_wkups } | ||
|
|
||
| /// `ri_interrupt_wkups`: TBD | ||
| public var interruptWakeups: UInt64 { rawValue.ri_interrupt_wkups } | ||
|
|
||
| /// `ri_pageins`: TBD | ||
| public var pageIns: UInt64 { rawValue.ri_pageins } | ||
|
|
||
| /// `ri_wired_size`: TBD | ||
| public var wiredSize: UInt64 { rawValue.ri_wired_size } | ||
|
|
||
| /// `ri_resident_size`: TBD | ||
| public var residentSize: UInt64 { rawValue.ri_resident_size } | ||
|
|
||
| /// `ri_phys_footprint`: TBD | ||
| public var physicalFootprint: UInt64 { rawValue.ri_phys_footprint } | ||
|
|
||
| /// `ri_proc_start_abstime`: TBD | ||
| public var processStartAbsoluteTime: UInt64 { rawValue.ri_proc_start_abstime } | ||
|
|
||
| /// `ri_proc_exit_abstime`: TBD | ||
| public var processExitAbsoluteTime: UInt64 { rawValue.ri_proc_exit_abstime } | ||
|
|
||
| /// `ri_child_user_time`: TBD | ||
| public var childUserTime: UInt64 { rawValue.ri_child_user_time } | ||
|
|
||
| /// `ri_child_system_time`: TBD | ||
| public var childSystemTime: UInt64 { rawValue.ri_child_system_time } | ||
|
|
||
| /// `ri_child_pkg_idle_wkups`: TBD | ||
| public var childPkgIdleWakeups: UInt64 { rawValue.ri_child_pkg_idle_wkups } | ||
|
|
||
| /// `ri_child_interrupt_wkups`: TBD | ||
| public var childInterruptWakeups: UInt64 { rawValue.ri_child_interrupt_wkups } | ||
|
|
||
| /// `ri_child_pageins`: TBD | ||
| public var childPageIns: UInt64 { rawValue.ri_child_pageins } | ||
|
|
||
| /// `ri_child_elapsed_abstime`: TBD | ||
| public var childElapsedAbsoluteTime: UInt64 { rawValue.ri_child_elapsed_abstime } | ||
|
|
||
| /// `ri_diskio_bytesread`: TBD | ||
| public var diskIOBytesRead: UInt64 { rawValue.ri_diskio_bytesread } | ||
|
|
||
| /// `ri_diskio_byteswritten`: TBD | ||
| public var diskIOBytesWritten: UInt64 { rawValue.ri_diskio_byteswritten } | ||
|
|
||
| /// `ri_cpu_time_qos_default`: TBD | ||
| public var cpuTimeQOSDefault: UInt64 { rawValue.ri_cpu_time_qos_default } | ||
|
|
||
| /// `ri_cpu_time_qos_maintenance`: TBD | ||
| public var cpuTimeQOSMaintenance: UInt64 { rawValue.ri_cpu_time_qos_maintenance } | ||
|
|
||
| /// `ri_cpu_time_qos_background`: TBD | ||
| public var cpuTimeQOSBackground: UInt64 { rawValue.ri_cpu_time_qos_background } | ||
|
|
||
| /// `ri_cpu_time_qos_utility`: TBD | ||
| public var cpuTimeQOSUtility: UInt64 { rawValue.ri_cpu_time_qos_utility } | ||
|
|
||
| /// `ri_cpu_time_qos_legacy`: TBD | ||
| public var cpuTimeQOSLegacy: UInt64 { rawValue.ri_cpu_time_qos_legacy } | ||
|
|
||
| /// `ri_cpu_time_qos_user_initiated`: TBD | ||
| public var cpuTimeQOSUserInitiated: UInt64 { rawValue.ri_cpu_time_qos_user_initiated } | ||
|
|
||
| /// `ri_cpu_time_qos_user_interactive`: TBD | ||
| public var cpuTimeQOSUserInteractive: UInt64 { rawValue.ri_cpu_time_qos_user_interactive } | ||
|
|
||
| /// `ri_billed_system_time`: TBD | ||
| public var billedSystemTime: UInt64 { rawValue.ri_billed_system_time } | ||
|
|
||
| /// `ri_serviced_system_time`: TBD | ||
| public var servicedSystemTime: UInt64 { rawValue.ri_serviced_system_time } | ||
|
|
||
| /// `ri_logical_writes`: TBD | ||
| public var logicalWrites: UInt64 { rawValue.ri_logical_writes } | ||
|
|
||
| /// `ri_lifetime_max_phys_footprint`: TBD | ||
| public var lifetimeMaxPhysicalFootprint: UInt64 { rawValue.ri_lifetime_max_phys_footprint } | ||
|
|
||
| /// `ri_instructions`: TBD | ||
| public var instructions: UInt64 { rawValue.ri_instructions } | ||
|
|
||
| /// `ri_cycles`: TBD | ||
| public var cycles: UInt64 { rawValue.ri_cycles } | ||
|
|
||
| /// `ri_billed_energy`: TBD | ||
| public var billedEnergy: UInt64 { rawValue.ri_billed_energy } | ||
|
|
||
| /// `ri_serviced_energy`: TBD | ||
| public var servicedEnergy: UInt64 { rawValue.ri_serviced_energy } | ||
|
|
||
| /// `ri_interval_max_phys_footprint`: TBD | ||
| public var intervalMaxPhysicalFootprint: UInt64 { rawValue.ri_interval_max_phys_footprint } | ||
|
|
||
| /// `ri_runnable_time`: TBD | ||
| public var runnableTime: UInt64 { rawValue.ri_runnable_time } | ||
|
|
||
| /// `ri_flags`: TBD | ||
| public var flags: UInt64 { rawValue.ri_flags } | ||
|
|
||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
|
|
||
| // FIXME(DO NOT MERGE): system_foo wrappers for these and mocking | ||
| import CSystem | ||
|
|
||
| extension ProcessID { | ||
| public struct TaskInfo: RawRepresentable/*, Hashable, Codable*/ { | ||
| /// The raw C process id. | ||
| @_alwaysEmitIntoClient | ||
| public let rawValue: CInterop.ProcTaskInfo | ||
|
|
||
| /// Creates a strongly-typed process id from a raw C pid | ||
| @_alwaysEmitIntoClient | ||
| public init(rawValue: CInterop.ProcTaskInfo) { self.rawValue = rawValue } | ||
|
|
||
| fileprivate init(_ rawValue: CInterop.ProcTaskInfo) { | ||
| self.init(rawValue: rawValue) | ||
| } | ||
| } | ||
| public func getTaskInfo() throws -> TaskInfo { | ||
| var result = TaskInfo.RawValue() | ||
| try withUnsafeMutableBytes(of: &result) { | ||
| let val = proc_pidinfo(self.rawValue, PROC_PIDTASKINFO, 0, $0.baseAddress, Int32($0.count)) | ||
| // What is this wacky shenanigans? | ||
| guard MemoryLayout<TaskInfo.RawValue>.stride == val else { | ||
| throw Errno(rawValue: val) | ||
| } | ||
| } | ||
| return TaskInfo(result) | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what the intended scope is for this pull request, but a common need is to get the path and name for a PID. |
||
| } | ||
|
|
||
| extension ProcessID.TaskInfo { | ||
|
|
||
| /// `pti_virtual_size`: virtual memory size (bytes) | ||
| public var virtualSize: UInt64 { UInt64(rawValue.pti_virtual_size) } | ||
|
|
||
| /// `pti_resident_size`: resident memory size (bytes) | ||
| public var residentSize: UInt64 { UInt64(rawValue.pti_resident_size) } | ||
|
|
||
| /// `pti_total_user`: total time | ||
| public var totalUserTime: UInt64 { UInt64(rawValue.pti_total_user) } | ||
|
|
||
| /// `pti_threads_user`: existing threads only | ||
| public var userThreads: UInt64 { UInt64(rawValue.pti_threads_user) } | ||
|
|
||
| /// `pti_policy`: default policy for new threads | ||
| public var policy: Int { Int(rawValue.pti_policy) } | ||
|
|
||
| /// `pti_faults`: number of page faults | ||
| public var pageFaults: Int { Int(rawValue.pti_faults) } | ||
|
|
||
| /// `pti_pageins`: number of actual pageins | ||
| public var pageIns: Int { Int(rawValue.pti_pageins) } | ||
|
|
||
| /// `pti_cow_faults`: number of copy-on-write faults | ||
| public var cowFaults: Int { Int(rawValue.pti_cow_faults) } | ||
|
|
||
| /// `pti_messages_sent`: number of messages sent | ||
| public var messagesSent: Int { Int(rawValue.pti_messages_sent) } | ||
|
|
||
| /// `pti_messages_received`: number of messages received | ||
| public var messagesReceived: Int { Int(rawValue.pti_messages_received) } | ||
|
|
||
| /// `pti_syscalls_mach`: number of mach system calls | ||
| public var syscallsMach: Int { Int(rawValue.pti_syscalls_mach) } | ||
|
|
||
| /// `pti_syscalls_unix`: number of unix system calls | ||
| public var syscallsUnix: Int { Int(rawValue.pti_syscalls_unix) } | ||
|
|
||
| /// `pti_csw`: number of context switches | ||
| public var contextSwitches: Int { Int(rawValue.pti_csw) } | ||
|
|
||
| /// `pti_threadnum`: number of threads in the task | ||
| public var taskThreads: Int { Int(rawValue.pti_threadnum) } | ||
|
|
||
| /// `pti_numrunning`: number of running threads | ||
| public var runningThreads: Int { Int(rawValue.pti_numrunning) } | ||
|
|
||
| /// `pti_priority`: task priority | ||
| public var taskPriority: Int { Int(rawValue.pti_priority) } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foundation already has a wrapper for
uuid_t-- perhaps we should investigate shrinking it into System.