use crate::sys::{self as sys, zx_duration_t};
use crate::{object_get_info_single, ok, AsHandleRef, Channel, Handle, ObjectQuery, Status, Topic};
use bitflags::bitflags;
bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ExceptionChannelOptions: u32 {
const DEBUGGER = sys::ZX_EXCEPTION_CHANNEL_DEBUGGER;
}
}
sys::zx_info_task_runtime_t!(TaskRuntimeInfo);
impl From<sys::zx_info_task_runtime_t> for TaskRuntimeInfo {
fn from(
sys::zx_info_task_runtime_t { cpu_time, queue_time, page_fault_time, lock_contention_time }: sys::zx_info_task_runtime_t,
) -> TaskRuntimeInfo {
TaskRuntimeInfo { cpu_time, queue_time, page_fault_time, lock_contention_time }
}
}
impl std::ops::Add for TaskRuntimeInfo {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
cpu_time: self.cpu_time + rhs.cpu_time,
queue_time: self.queue_time + rhs.queue_time,
page_fault_time: self.page_fault_time + rhs.page_fault_time,
lock_contention_time: self.lock_contention_time + rhs.lock_contention_time,
}
}
}
impl std::ops::AddAssign for TaskRuntimeInfo {
fn add_assign(&mut self, rhs: Self) {
self.cpu_time += rhs.cpu_time;
self.queue_time += rhs.queue_time;
self.page_fault_time += rhs.page_fault_time;
self.lock_contention_time += rhs.lock_contention_time;
}
}
impl std::ops::Sub for TaskRuntimeInfo {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
cpu_time: self.cpu_time - rhs.cpu_time,
queue_time: self.queue_time - rhs.queue_time,
page_fault_time: self.page_fault_time - rhs.page_fault_time,
lock_contention_time: self.lock_contention_time - rhs.lock_contention_time,
}
}
}
impl std::ops::SubAssign for TaskRuntimeInfo {
fn sub_assign(&mut self, rhs: Self) {
self.cpu_time -= rhs.cpu_time;
self.queue_time -= rhs.queue_time;
self.page_fault_time -= rhs.page_fault_time;
self.lock_contention_time -= rhs.lock_contention_time;
}
}
unsafe impl ObjectQuery for TaskRuntimeInfo {
const TOPIC: Topic = Topic::TASK_RUNTIME;
type InfoTy = TaskRuntimeInfo;
}
pub trait Task: AsHandleRef {
fn kill(&self) -> Result<(), Status> {
ok(unsafe { sys::zx_task_kill(self.raw_handle()) })
}
fn suspend(&self) -> Result<Handle, Status> {
let mut suspend_token = 0;
let status = unsafe { sys::zx_task_suspend(self.raw_handle(), &mut suspend_token) };
ok(status)?;
unsafe { Ok(Handle::from_raw(suspend_token)) }
}
fn create_exception_channel_with_opts(
&self,
opts: ExceptionChannelOptions,
) -> Result<Channel, Status> {
let mut handle = 0;
let status = unsafe {
sys::zx_task_create_exception_channel(self.raw_handle(), opts.bits(), &mut handle)
};
ok(status)?;
unsafe { Ok(Channel::from(Handle::from_raw(handle))) }
}
fn create_exception_channel(&self) -> Result<Channel, Status> {
self.create_exception_channel_with_opts(ExceptionChannelOptions::from_bits_truncate(0))
}
fn get_runtime_info(&self) -> Result<TaskRuntimeInfo, Status> {
object_get_info_single::<TaskRuntimeInfo>(self.as_handle_ref())
}
}