mirror of
https://github.com/servo/servo.git
synced 2025-06-09 09:03:23 +00:00
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>
79 lines
2.2 KiB
Rust
79 lines
2.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use std::process::Child;
|
|
|
|
use crossbeam_channel::{Receiver, Select};
|
|
use log::{debug, warn};
|
|
use profile_traits::mem::{ProfilerChan, ProfilerMsg};
|
|
|
|
pub enum Process {
|
|
Unsandboxed(Child),
|
|
Sandboxed(u32),
|
|
}
|
|
|
|
impl Process {
|
|
fn pid(&self) -> u32 {
|
|
match self {
|
|
Self::Unsandboxed(child) => child.id(),
|
|
Self::Sandboxed(pid) => *pid,
|
|
}
|
|
}
|
|
|
|
fn wait(&mut self) {
|
|
match self {
|
|
Self::Unsandboxed(child) => {
|
|
let _ = child.wait();
|
|
},
|
|
Self::Sandboxed(_pid) => {
|
|
// TODO: use nix::waitpid() on supported platforms.
|
|
warn!("wait() is not yet implemented for sandboxed processes.");
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
type ProcessReceiver = Receiver<Result<(), ipc_channel::Error>>;
|
|
|
|
pub(crate) struct ProcessManager {
|
|
processes: Vec<(Process, ProcessReceiver)>,
|
|
mem_profiler_chan: ProfilerChan,
|
|
}
|
|
|
|
impl ProcessManager {
|
|
pub fn new(mem_profiler_chan: ProfilerChan) -> Self {
|
|
Self {
|
|
processes: vec![],
|
|
mem_profiler_chan,
|
|
}
|
|
}
|
|
|
|
pub fn add(&mut self, receiver: ProcessReceiver, process: Process) {
|
|
debug!("Adding process pid={}", process.pid());
|
|
self.processes.push((process, receiver));
|
|
}
|
|
|
|
pub fn register<'a>(&'a self, select: &mut Select<'a>) {
|
|
for (_, receiver) in &self.processes {
|
|
select.recv(receiver);
|
|
}
|
|
}
|
|
|
|
pub fn receiver_at(&self, index: usize) -> &ProcessReceiver {
|
|
let (_, receiver) = &self.processes[index];
|
|
receiver
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|