| // Copyright 2023 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| pub mod restorable; | |
| pub mod simple; | |
| use crate::ProcessId; | |
| use crate::ProcessState; | |
| use crate::ThreadId; | |
| use crate::ThreadState; | |
| pub trait ProcessContext { | |
| type TM<'a>: ThreadMap | |
| where | |
| Self: 'a; | |
| fn timestamp(&self) -> u64; | |
| fn state(&self) -> ProcessState; | |
| fn thread_map(&mut self) -> Self::TM<'_>; | |
| } | |
| pub trait ProcessMap { | |
| type P<'a>: ProcessContext | |
| where | |
| Self: 'a; | |
| /// Insert a new process or update a process if exists. | |
| /// | |
| /// Returns [None] if inserting. | |
| /// | |
| /// Returns [ProcessContext] if the process exists and is updated. | |
| /// | |
| /// If an entry for `process_id` exists whose timestamp does not equal `timestamp`, that process | |
| /// entry is removed from the map before the new process entry is inserted, and [None] is | |
| /// returned. | |
| fn insert_or_update( | |
| &mut self, | |
| process_id: ProcessId, | |
| timestamp: u64, | |
| state: ProcessState, | |
| ) -> Option<Self::P<'_>>; | |
| fn get_process(&mut self, process_id: ProcessId) -> Option<Self::P<'_>>; | |
| /// Remove a process. | |
| /// | |
| /// `timestamp` is used to identify the process with `process_id` if it is `Option::Some`. | |
| /// Otherwise this does not check the stored timestamp in the map. | |
| fn remove_process(&mut self, process_id: ProcessId, timestamp: Option<u64>); | |
| /// Reduce storage size by compacting holes left by deleted processes and threads. | |
| /// | |
| /// NOTE: compact() should be called on every process/thread context update. It still works | |
| /// without compact()ing, but next compact() will take longer time for accumulating removed | |
| /// contexts which will cause inconsistent latency of the process/thread context update latency | |
| /// and performance degradation. [The Tail at Scale](https://research.google/pubs/pub40801/). | |
| fn compact(&mut self); | |
| } | |
| pub trait ThreadMap { | |
| /// Insert a new thread or update a thread if exist. | |
| /// | |
| /// Before inserting a new thread GC threads in the map. This is to avoid useless memory | |
| /// consumption of from dead threads for the case a process spawns many short-term threads while | |
| /// the process state keeps the same. The `fn_is_thread_alive` is used to check whether the | |
| /// thread is alive or not. | |
| fn insert_or_update<F>( | |
| &mut self, | |
| thread_id: ThreadId, | |
| timestamp: u64, | |
| state: ThreadState, | |
| fn_is_thread_alive: F, | |
| ) where | |
| F: FnMut(&ThreadId) -> bool; | |
| fn retain_threads<F>(&mut self, f: F) | |
| where | |
| F: FnMut(&ThreadId, &ThreadEntry) -> bool; | |
| fn remove_thread(&mut self, thread_id: ThreadId); | |
| } | |
| pub struct ThreadEntry { | |
| pub timestamp: u64, | |
| pub state: ThreadState, | |
| } |