diagnostics/task_metrics/
runtime_stats_source.rsuse async_trait::async_trait;
use fidl_fuchsia_diagnostics_types::{ComponentDiagnostics, Task as DiagnosticsTask, TaskUnknown};
use futures::channel::oneshot;
use hooks::RuntimeInfo;
use zx::{self as zx, sys as zx_sys, AsHandleRef, Task};
#[async_trait]
pub trait RuntimeStatsSource {
fn koid(&self) -> Result<zx_sys::zx_koid_t, zx::Status>;
fn handle_ref(&self) -> zx::HandleRef<'_>;
async fn get_runtime_info(&self) -> Result<zx::TaskRuntimeInfo, zx::Status>;
}
#[async_trait]
pub trait RuntimeStatsContainer<T: RuntimeStatsSource> {
fn take_component_task(&mut self) -> Option<T>;
fn take_parent_task(&mut self) -> Option<T>;
}
#[async_trait]
pub trait ComponentStartedInfo<T, S>
where
T: RuntimeStatsContainer<S>,
S: RuntimeStatsSource,
{
async fn get_receiver(&self) -> Option<oneshot::Receiver<T>>;
fn start_time(&self) -> zx::BootInstant;
}
#[async_trait]
impl RuntimeStatsSource for DiagnosticsTask {
fn koid(&self) -> Result<zx_sys::zx_koid_t, zx::Status> {
let info = match &self {
DiagnosticsTask::Job(job) => job.basic_info(),
DiagnosticsTask::Process(process) => process.basic_info(),
DiagnosticsTask::Thread(thread) => thread.basic_info(),
TaskUnknown!() => {
unreachable!("only jobs, threads and processes are tasks");
}
}?;
Ok(info.koid.raw_koid())
}
fn handle_ref(&self) -> zx::HandleRef<'_> {
match &self {
DiagnosticsTask::Job(job) => job.as_handle_ref(),
DiagnosticsTask::Process(process) => process.as_handle_ref(),
DiagnosticsTask::Thread(thread) => thread.as_handle_ref(),
TaskUnknown!() => {
unreachable!("only jobs, threads and processes are tasks");
}
}
}
async fn get_runtime_info(&self) -> Result<zx::TaskRuntimeInfo, zx::Status> {
match &self {
DiagnosticsTask::Job(job) => job.get_runtime_info(),
DiagnosticsTask::Process(process) => process.get_runtime_info(),
DiagnosticsTask::Thread(thread) => thread.get_runtime_info(),
TaskUnknown!() => {
unreachable!("only jobs, threads and processes are tasks");
}
}
}
}
#[async_trait]
impl RuntimeStatsContainer<DiagnosticsTask> for ComponentDiagnostics {
fn take_component_task(&mut self) -> Option<DiagnosticsTask> {
self.tasks.as_mut().and_then(|tasks| tasks.component_task.take())
}
fn take_parent_task(&mut self) -> Option<DiagnosticsTask> {
self.tasks.as_mut().and_then(|tasks| tasks.parent_task.take())
}
}
#[async_trait]
impl ComponentStartedInfo<ComponentDiagnostics, DiagnosticsTask> for RuntimeInfo {
async fn get_receiver(&self) -> Option<oneshot::Receiver<ComponentDiagnostics>> {
let mut receiver_guard = self.diagnostics_receiver.lock().await;
receiver_guard.take()
}
fn start_time(&self) -> zx::BootInstant {
self.start_time
}
}