mirror of
https://github.com/servo/servo.git
synced 2025-08-08 23:15:33 +01:00
Improve scheduling of the memory profiler. (#35618)
Switch the delay to be used between the end of a previous run and the next, instead of the start of consecutive runs. That ensure that we don't enqueue messages when processing is slower than the delay. Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
d446b63cfd
commit
678f0c9fdc
3 changed files with 25 additions and 2 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -5811,6 +5811,7 @@ dependencies = [
|
|||
"base",
|
||||
"ipc-channel",
|
||||
"libc",
|
||||
"parking_lot",
|
||||
"profile_traits",
|
||||
"regex",
|
||||
"serde",
|
||||
|
|
|
@ -14,6 +14,7 @@ path = "lib.rs"
|
|||
[dependencies]
|
||||
base = { workspace = true }
|
||||
ipc-channel = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
profile_traits = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
use std::borrow::ToOwned;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use ipc_channel::ipc::{self, IpcReceiver};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use parking_lot::{Condvar, Mutex};
|
||||
use profile_traits::mem::{
|
||||
ProfilerChan, ProfilerMsg, ReportKind, Reporter, ReporterRequest, ReportsChan,
|
||||
};
|
||||
|
@ -26,6 +28,10 @@ pub struct Profiler {
|
|||
|
||||
/// Instant at which this profiler was created.
|
||||
created: Instant,
|
||||
|
||||
/// Used to notify the timer thread that the profiler is done
|
||||
/// with processing a `ProfilerMsg::Print` message.
|
||||
notifier: Arc<(Mutex<bool>, Condvar)>,
|
||||
}
|
||||
|
||||
const JEMALLOC_HEAP_ALLOCATED_STR: &str = "jemalloc-heap-allocated";
|
||||
|
@ -35,6 +41,9 @@ impl Profiler {
|
|||
pub fn create(period: Option<f64>) -> ProfilerChan {
|
||||
let (chan, port) = ipc::channel().unwrap();
|
||||
|
||||
let notifier = Arc::new((Mutex::new(false), Condvar::new()));
|
||||
let notifier2 = Arc::clone(¬ifier);
|
||||
|
||||
// Create the timer thread if a period was provided.
|
||||
if let Some(period) = period {
|
||||
let chan = chan.clone();
|
||||
|
@ -42,9 +51,15 @@ impl Profiler {
|
|||
.name("MemoryProfTimer".to_owned())
|
||||
.spawn(move || loop {
|
||||
thread::sleep(Duration::from_secs_f64(period));
|
||||
let (mutex, cvar) = &*notifier;
|
||||
let mut done = mutex.lock();
|
||||
*done = false;
|
||||
if chan.send(ProfilerMsg::Print).is_err() {
|
||||
break;
|
||||
}
|
||||
if !*done {
|
||||
cvar.wait(&mut done);
|
||||
}
|
||||
})
|
||||
.expect("Thread spawning failed");
|
||||
}
|
||||
|
@ -54,7 +69,7 @@ impl Profiler {
|
|||
thread::Builder::new()
|
||||
.name("MemoryProfiler".to_owned())
|
||||
.spawn(move || {
|
||||
let mut mem_profiler = Profiler::new(port);
|
||||
let mut mem_profiler = Profiler::new(port, notifier2);
|
||||
mem_profiler.start();
|
||||
})
|
||||
.expect("Thread spawning failed");
|
||||
|
@ -80,11 +95,12 @@ impl Profiler {
|
|||
mem_profiler_chan
|
||||
}
|
||||
|
||||
pub fn new(port: IpcReceiver<ProfilerMsg>) -> Profiler {
|
||||
pub fn new(port: IpcReceiver<ProfilerMsg>, notifier: Arc<(Mutex<bool>, Condvar)>) -> Profiler {
|
||||
Profiler {
|
||||
port,
|
||||
reporters: HashMap::new(),
|
||||
created: Instant::now(),
|
||||
notifier,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +133,11 @@ impl Profiler {
|
|||
|
||||
ProfilerMsg::Print => {
|
||||
self.handle_print_msg();
|
||||
// Notify the timer thread.
|
||||
let (mutex, cvar) = &*self.notifier;
|
||||
let mut done = mutex.lock();
|
||||
*done = true;
|
||||
cvar.notify_one();
|
||||
true
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue