zx/
task.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::sys::{self as sys, zx_duration_t};
6use crate::{object_get_info_single, ok, AsHandleRef, Channel, Handle, ObjectQuery, Status, Topic};
7use bitflags::bitflags;
8
9bitflags! {
10    /// Options that may be used with `Task::create_exception_channel`
11    #[repr(transparent)]
12    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13    pub struct ExceptionChannelOptions: u32 {
14        const DEBUGGER = sys::ZX_EXCEPTION_CHANNEL_DEBUGGER;
15    }
16}
17
18sys::zx_info_task_runtime_t!(TaskRuntimeInfo);
19
20impl From<sys::zx_info_task_runtime_t> for TaskRuntimeInfo {
21    fn from(
22        sys::zx_info_task_runtime_t { cpu_time, queue_time, page_fault_time, lock_contention_time }: sys::zx_info_task_runtime_t,
23    ) -> TaskRuntimeInfo {
24        TaskRuntimeInfo { cpu_time, queue_time, page_fault_time, lock_contention_time }
25    }
26}
27
28impl std::ops::Add for TaskRuntimeInfo {
29    type Output = Self;
30    fn add(self, rhs: Self) -> Self::Output {
31        Self {
32            cpu_time: self.cpu_time + rhs.cpu_time,
33            queue_time: self.queue_time + rhs.queue_time,
34            page_fault_time: self.page_fault_time + rhs.page_fault_time,
35            lock_contention_time: self.lock_contention_time + rhs.lock_contention_time,
36        }
37    }
38}
39
40impl std::ops::AddAssign for TaskRuntimeInfo {
41    fn add_assign(&mut self, rhs: Self) {
42        self.cpu_time += rhs.cpu_time;
43        self.queue_time += rhs.queue_time;
44        self.page_fault_time += rhs.page_fault_time;
45        self.lock_contention_time += rhs.lock_contention_time;
46    }
47}
48
49impl std::ops::Sub for TaskRuntimeInfo {
50    type Output = Self;
51    fn sub(self, rhs: Self) -> Self::Output {
52        Self {
53            cpu_time: self.cpu_time - rhs.cpu_time,
54            queue_time: self.queue_time - rhs.queue_time,
55            page_fault_time: self.page_fault_time - rhs.page_fault_time,
56            lock_contention_time: self.lock_contention_time - rhs.lock_contention_time,
57        }
58    }
59}
60
61impl std::ops::SubAssign for TaskRuntimeInfo {
62    fn sub_assign(&mut self, rhs: Self) {
63        self.cpu_time -= rhs.cpu_time;
64        self.queue_time -= rhs.queue_time;
65        self.page_fault_time -= rhs.page_fault_time;
66        self.lock_contention_time -= rhs.lock_contention_time;
67    }
68}
69
70unsafe impl ObjectQuery for TaskRuntimeInfo {
71    const TOPIC: Topic = Topic::TASK_RUNTIME;
72    type InfoTy = TaskRuntimeInfo;
73}
74
75pub trait Task: AsHandleRef {
76    /// Kill the given task (job, process, or thread).
77    ///
78    /// Wraps the
79    /// [zx_task_kill](https://fuchsia.dev/fuchsia-src/reference/syscalls/task_kill.md)
80    /// syscall.
81    // TODO(https://fxbug.dev/42152215): guaranteed to return an error when called on a Thread.
82    fn kill(&self) -> Result<(), Status> {
83        ok(unsafe { sys::zx_task_kill(self.raw_handle()) })
84    }
85
86    /// Suspend the given task
87    ///
88    /// Wraps the
89    /// [zx_task_suspend](https://fuchsia.dev/fuchsia-src/reference/syscalls/task_suspend.md)
90    /// syscall.
91    ///
92    /// Resume the task by closing the returned handle.
93    fn suspend(&self) -> Result<Handle, Status> {
94        let mut suspend_token = 0;
95        let status = unsafe { sys::zx_task_suspend(self.raw_handle(), &mut suspend_token) };
96        ok(status)?;
97        unsafe { Ok(Handle::from_raw(suspend_token)) }
98    }
99
100    /// Create an exception channel (with options) for the task.
101    ///
102    /// Wraps the
103    /// [zx_task_create_exception_channel](https://fuchsia.dev/fuchsia-src/reference/syscalls/task_create_exception_channel.md)
104    /// syscall.
105    fn create_exception_channel_with_opts(
106        &self,
107        opts: ExceptionChannelOptions,
108    ) -> Result<Channel, Status> {
109        let mut handle = 0;
110        let status = unsafe {
111            sys::zx_task_create_exception_channel(self.raw_handle(), opts.bits(), &mut handle)
112        };
113        ok(status)?;
114        unsafe { Ok(Channel::from(Handle::from_raw(handle))) }
115    }
116
117    /// Create an exception channel for the task.
118    ///
119    /// Wraps the
120    /// [zx_task_create_exception_channel](https://fuchsia.dev/fuchsia-src/reference/syscalls/task_create_exception_channel.md)
121    /// syscall.
122    fn create_exception_channel(&self) -> Result<Channel, Status> {
123        self.create_exception_channel_with_opts(ExceptionChannelOptions::from_bits_truncate(0))
124    }
125
126    /// Returns the runtime information for the task.
127    ///
128    /// Wraps the
129    /// [zx_object_get_info]() syscall with `ZX_INFO_TASK_RUNTIME` as the topic.
130    fn get_runtime_info(&self) -> Result<TaskRuntimeInfo, Status> {
131        object_get_info_single::<TaskRuntimeInfo>(self.as_handle_ref())
132    }
133}