mirror of
https://github.com/servo/servo.git
synced 2025-08-10 07:55:33 +01:00
Make the memory reporting multi-process aware (#35863)
So far the memory reporter aggregates reports from all processes, and runs the system reporter only in the main process. Instead it is desirable to have per-process reports. We do so by: - creating a ProcessReports struct that holds includes the pid in addition to the reports themselves. - running the system memory reporter also in content processes. - updating the about:memory page to create one report per process, and add useful information like the pid and the urls loaded in a given process. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors  Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
76edcff202
commit
aef8537d75
15 changed files with 551 additions and 424 deletions
|
@ -39,6 +39,7 @@ media = { path = "../media" }
|
|||
net = { path = "../net" }
|
||||
net_traits = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
profile = { path = "../profile" }
|
||||
profile_traits = { workspace = true }
|
||||
script_layout_interface = { workspace = true }
|
||||
script_traits = { workspace = true }
|
||||
|
|
|
@ -712,7 +712,7 @@ where
|
|||
// namespace 0 for the embedder, and 0 for the constellation
|
||||
next_pipeline_namespace_id: PipelineNamespaceId(2),
|
||||
time_profiler_chan: state.time_profiler_chan,
|
||||
mem_profiler_chan: state.mem_profiler_chan,
|
||||
mem_profiler_chan: state.mem_profiler_chan.clone(),
|
||||
phantom: PhantomData,
|
||||
webdriver: WebDriverData::new(),
|
||||
document_states: HashMap::new(),
|
||||
|
@ -739,7 +739,7 @@ where
|
|||
active_media_session: None,
|
||||
rippy_data,
|
||||
user_content_manager: state.user_content_manager,
|
||||
process_manager: ProcessManager::new(),
|
||||
process_manager: ProcessManager::new(state.mem_profiler_chan),
|
||||
};
|
||||
|
||||
constellation.run();
|
||||
|
|
|
@ -32,6 +32,8 @@ use media::WindowGLContext;
|
|||
use net::image_cache::ImageCacheImpl;
|
||||
use net_traits::ResourceThreads;
|
||||
use net_traits::image_cache::ImageCache;
|
||||
use profile::system_reporter;
|
||||
use profile_traits::mem::{ProfilerMsg, Reporter};
|
||||
use profile_traits::{mem as profile_mem, time};
|
||||
use script_layout_interface::{LayoutFactory, ScriptThreadFactory};
|
||||
use script_traits::{
|
||||
|
@ -591,4 +593,24 @@ impl UnprivilegedPipelineContent {
|
|||
pub fn prefs(&self) -> &Preferences {
|
||||
&self.prefs
|
||||
}
|
||||
|
||||
pub fn register_system_memory_reporter(&self) {
|
||||
// Register the system memory reporter, which will run on its own thread. It never needs to
|
||||
// be unregistered, because as long as the memory profiler is running the system memory
|
||||
// reporter can make measurements.
|
||||
let (system_reporter_sender, system_reporter_receiver) =
|
||||
ipc::channel().expect("failed to create ipc channel");
|
||||
ROUTER.add_typed_route(
|
||||
system_reporter_receiver,
|
||||
Box::new(|message| {
|
||||
if let Ok(request) = message {
|
||||
system_reporter::collect_reports(request);
|
||||
}
|
||||
}),
|
||||
);
|
||||
self.mem_profiler_chan.send(ProfilerMsg::RegisterReporter(
|
||||
format!("system-content-{}", std::process::id()),
|
||||
Reporter(system_reporter_sender),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::process::Child;
|
|||
|
||||
use crossbeam_channel::{Receiver, Select};
|
||||
use log::{debug, warn};
|
||||
use profile_traits::mem::{ProfilerChan, ProfilerMsg};
|
||||
|
||||
pub enum Process {
|
||||
Unsandboxed(Child),
|
||||
|
@ -37,11 +38,15 @@ type ProcessReceiver = Receiver<Result<(), ipc_channel::Error>>;
|
|||
|
||||
pub(crate) struct ProcessManager {
|
||||
processes: Vec<(Process, ProcessReceiver)>,
|
||||
mem_profiler_chan: ProfilerChan,
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
pub fn new() -> Self {
|
||||
Self { processes: vec![] }
|
||||
pub fn new(mem_profiler_chan: ProfilerChan) -> Self {
|
||||
Self {
|
||||
processes: vec![],
|
||||
mem_profiler_chan,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, receiver: ProcessReceiver, process: Process) {
|
||||
|
@ -63,6 +68,12 @@ impl ProcessManager {
|
|||
pub fn remove(&mut self, index: usize) {
|
||||
let (mut process, _) = self.processes.swap_remove(index);
|
||||
debug!("Removing process pid={}", process.pid());
|
||||
// Unregister this process system memory profiler
|
||||
self.mem_profiler_chan
|
||||
.send(ProfilerMsg::UnregisterReporter(format!(
|
||||
"system-content-{}",
|
||||
process.pid()
|
||||
)));
|
||||
process.wait();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue