use std::cmp::Ordering;
use std::hash::Hash;
use crate::frame_table::InternalFrameLocation;
use crate::global_lib_table::{GlobalLibTable, LibraryHandle};
use crate::lib_mappings::LibMappings;
use crate::Timestamp;
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct ThreadHandle(pub(crate) usize);
#[derive(Debug)]
pub struct Process {
pid: String,
name: String,
threads: Vec<ThreadHandle>,
start_time: Timestamp,
end_time: Option<Timestamp>,
libs: LibMappings<LibraryHandle>,
}
impl Process {
pub fn new(name: &str, pid: String, start_time: Timestamp) -> Self {
Self {
pid,
threads: Vec::new(),
libs: LibMappings::new(),
start_time,
end_time: None,
name: name.to_owned(),
}
}
pub fn thread_handle_for_allocations(&self) -> Option<ThreadHandle> {
self.threads.first().cloned()
}
pub fn set_start_time(&mut self, start_time: Timestamp) {
self.start_time = start_time;
}
pub fn start_time(&self) -> Timestamp {
self.start_time
}
pub fn set_end_time(&mut self, end_time: Timestamp) {
self.end_time = Some(end_time);
}
pub fn end_time(&self) -> Option<Timestamp> {
self.end_time
}
pub fn set_name(&mut self, name: &str) {
self.name = name.to_string();
}
pub fn name(&self) -> &str {
&self.name
}
pub fn add_thread(&mut self, thread: ThreadHandle) {
self.threads.push(thread);
}
pub fn pid(&self) -> &str {
&self.pid
}
pub fn cmp_for_json_order(&self, other: &Process) -> Ordering {
if let Some(ordering) = self.start_time.partial_cmp(&other.start_time) {
if ordering != Ordering::Equal {
return ordering;
}
}
self.pid.cmp(&other.pid)
}
pub fn threads(&self) -> &[ThreadHandle] {
&self.threads
}
pub fn convert_address(
&mut self,
global_libs: &mut GlobalLibTable,
kernel_libs: &mut LibMappings<LibraryHandle>,
address: u64,
) -> InternalFrameLocation {
match kernel_libs
.convert_address(address)
.or_else(|| self.libs.convert_address(address))
{
Some((relative_address, lib_handle)) => {
let global_lib_index = global_libs.index_for_used_lib(*lib_handle);
InternalFrameLocation::AddressInLib(relative_address, global_lib_index)
}
None => InternalFrameLocation::UnknownAddress(address),
}
}
pub fn add_lib_mapping(
&mut self,
lib: LibraryHandle,
start_avma: u64,
end_avma: u64,
relative_address_at_start: u32,
) {
self.libs
.add_mapping(start_avma, end_avma, relative_address_at_start, lib);
}
pub fn remove_lib_mapping(&mut self, start_avma: u64) {
self.libs.remove_mapping(start_avma);
}
pub fn remove_all_lib_mappings(&mut self) {
self.libs.clear();
}
}