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