mirror of
https://github.com/servo/servo.git
synced 2025-08-09 07:25:35 +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",
|
"base",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
"libc",
|
"libc",
|
||||||
|
"parking_lot",
|
||||||
"profile_traits",
|
"profile_traits",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -14,6 +14,7 @@ path = "lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base = { workspace = true }
|
base = { workspace = true }
|
||||||
ipc-channel = { workspace = true }
|
ipc-channel = { workspace = true }
|
||||||
|
parking_lot = { workspace = true }
|
||||||
profile_traits = { workspace = true }
|
profile_traits = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use ipc_channel::ipc::{self, IpcReceiver};
|
use ipc_channel::ipc::{self, IpcReceiver};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
|
use parking_lot::{Condvar, Mutex};
|
||||||
use profile_traits::mem::{
|
use profile_traits::mem::{
|
||||||
ProfilerChan, ProfilerMsg, ReportKind, Reporter, ReporterRequest, ReportsChan,
|
ProfilerChan, ProfilerMsg, ReportKind, Reporter, ReporterRequest, ReportsChan,
|
||||||
};
|
};
|
||||||
|
@ -26,6 +28,10 @@ pub struct Profiler {
|
||||||
|
|
||||||
/// Instant at which this profiler was created.
|
/// Instant at which this profiler was created.
|
||||||
created: Instant,
|
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";
|
const JEMALLOC_HEAP_ALLOCATED_STR: &str = "jemalloc-heap-allocated";
|
||||||
|
@ -35,6 +41,9 @@ impl Profiler {
|
||||||
pub fn create(period: Option<f64>) -> ProfilerChan {
|
pub fn create(period: Option<f64>) -> ProfilerChan {
|
||||||
let (chan, port) = ipc::channel().unwrap();
|
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.
|
// Create the timer thread if a period was provided.
|
||||||
if let Some(period) = period {
|
if let Some(period) = period {
|
||||||
let chan = chan.clone();
|
let chan = chan.clone();
|
||||||
|
@ -42,9 +51,15 @@ impl Profiler {
|
||||||
.name("MemoryProfTimer".to_owned())
|
.name("MemoryProfTimer".to_owned())
|
||||||
.spawn(move || loop {
|
.spawn(move || loop {
|
||||||
thread::sleep(Duration::from_secs_f64(period));
|
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() {
|
if chan.send(ProfilerMsg::Print).is_err() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if !*done {
|
||||||
|
cvar.wait(&mut done);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed");
|
||||||
}
|
}
|
||||||
|
@ -54,7 +69,7 @@ impl Profiler {
|
||||||
thread::Builder::new()
|
thread::Builder::new()
|
||||||
.name("MemoryProfiler".to_owned())
|
.name("MemoryProfiler".to_owned())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let mut mem_profiler = Profiler::new(port);
|
let mut mem_profiler = Profiler::new(port, notifier2);
|
||||||
mem_profiler.start();
|
mem_profiler.start();
|
||||||
})
|
})
|
||||||
.expect("Thread spawning failed");
|
.expect("Thread spawning failed");
|
||||||
|
@ -80,11 +95,12 @@ impl Profiler {
|
||||||
mem_profiler_chan
|
mem_profiler_chan
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(port: IpcReceiver<ProfilerMsg>) -> Profiler {
|
pub fn new(port: IpcReceiver<ProfilerMsg>, notifier: Arc<(Mutex<bool>, Condvar)>) -> Profiler {
|
||||||
Profiler {
|
Profiler {
|
||||||
port,
|
port,
|
||||||
reporters: HashMap::new(),
|
reporters: HashMap::new(),
|
||||||
created: Instant::now(),
|
created: Instant::now(),
|
||||||
|
notifier,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +133,11 @@ impl Profiler {
|
||||||
|
|
||||||
ProfilerMsg::Print => {
|
ProfilerMsg::Print => {
|
||||||
self.handle_print_msg();
|
self.handle_print_msg();
|
||||||
|
// Notify the timer thread.
|
||||||
|
let (mutex, cvar) = &*self.notifier;
|
||||||
|
let mut done = mutex.lock();
|
||||||
|
*done = true;
|
||||||
|
cvar.notify_one();
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue