bound sampler buffer

This commit is contained in:
Gregory Terzian 2019-03-31 15:02:01 +08:00
parent fcd6beb608
commit 0780298b80
8 changed files with 36 additions and 18 deletions

View file

@ -12,7 +12,7 @@ use msg::constellation_msg::{
}; };
use msg::constellation_msg::{HangAlert, HangAnnotation, HangMonitorAlert, SamplerControlMsg}; use msg::constellation_msg::{HangAlert, HangAnnotation, HangMonitorAlert, SamplerControlMsg};
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashMap; use std::collections::{HashMap, VecDeque};
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -153,10 +153,11 @@ pub struct BackgroundHangMonitorWorker {
port: Receiver<(MonitoredComponentId, MonitoredComponentMsg)>, port: Receiver<(MonitoredComponentId, MonitoredComponentMsg)>,
control_port: Receiver<SamplerControlMsg>, control_port: Receiver<SamplerControlMsg>,
sampling_duration: Option<Duration>, sampling_duration: Option<Duration>,
sampling_max_duration: Option<Duration>,
last_sample: Instant, last_sample: Instant,
creation: Instant, creation: Instant,
sampling_baseline: Instant, sampling_baseline: Instant,
samples: Vec<Sample>, samples: VecDeque<Sample>,
} }
impl BackgroundHangMonitorWorker { impl BackgroundHangMonitorWorker {
@ -173,10 +174,11 @@ impl BackgroundHangMonitorWorker {
port, port,
control_port, control_port,
sampling_duration: None, sampling_duration: None,
sampling_max_duration: None,
last_sample: Instant::now(), last_sample: Instant::now(),
sampling_baseline: Instant::now(), sampling_baseline: Instant::now(),
creation: Instant::now(), creation: Instant::now(),
samples: vec![], samples: Default::default(),
} }
} }
@ -239,9 +241,10 @@ impl BackgroundHangMonitorWorker {
}, },
recv(self.control_port) -> event => { recv(self.control_port) -> event => {
match event { match event {
Ok(SamplerControlMsg::Enable(rate)) => { Ok(SamplerControlMsg::Enable(rate, max_duration)) => {
println!("Enabling profiler."); println!("Enabling profiler.");
self.sampling_duration = Some(rate); self.sampling_duration = Some(rate);
self.sampling_max_duration = Some(max_duration);
self.sampling_baseline = Instant::now(); self.sampling_baseline = Instant::now();
None None
} }
@ -381,9 +384,15 @@ impl BackgroundHangMonitorWorker {
for (component_id, monitored) in self.monitored_components.iter_mut() { for (component_id, monitored) in self.monitored_components.iter_mut() {
let instant = Instant::now(); let instant = Instant::now();
if let Ok(stack) = monitored.sampler.suspend_and_sample_thread() { if let Ok(stack) = monitored.sampler.suspend_and_sample_thread() {
// TODO: support a bounded buffer that discards older samples. if self.sampling_baseline.elapsed() >
self.sampling_max_duration
.expect("Max duration has been set")
{
// Buffer is full, start discarding older samples.
self.samples.pop_front();
}
self.samples self.samples
.push(Sample(component_id.clone(), instant, stack)); .push_back(Sample(component_id.clone(), instant, stack));
} }
} }
} }

View file

@ -30,11 +30,15 @@ fn test_sampler() {
); );
const RATE: u64 = 10; const RATE: u64 = 10;
const MAX_DURATION: u64 = 10;
sampler_sender sampler_sender
.send(SamplerControlMsg::Enable(Duration::from_millis(RATE))) .send(SamplerControlMsg::Enable(
Duration::from_millis(RATE),
Duration::from_secs(MAX_DURATION),
))
.unwrap(); .unwrap();
thread::sleep(Duration::from_millis(30)); thread::sleep(Duration::from_millis(100));
sampler_sender.send(SamplerControlMsg::Disable).unwrap(); sampler_sender.send(SamplerControlMsg::Disable).unwrap();

View file

@ -95,8 +95,8 @@ pub enum WindowEvent {
ToggleWebRenderDebug(WebRenderDebugOption), ToggleWebRenderDebug(WebRenderDebugOption),
/// Capture current WebRender /// Capture current WebRender
CaptureWebRender, CaptureWebRender,
/// Toggle sampling profiler with the given sampling rate /// Toggle sampling profiler with the given sampling rate and max duration.
ToggleSamplingProfiler(Duration), ToggleSamplingProfiler(Duration, Duration),
} }
impl Debug for WindowEvent { impl Debug for WindowEvent {

View file

@ -1216,9 +1216,9 @@ where
self.forward_event(destination_pipeline_id, event); self.forward_event(destination_pipeline_id, event);
}, },
FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor), FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor),
FromCompositorMsg::EnableProfiler(rate) => { FromCompositorMsg::EnableProfiler(rate, max_duration) => {
for chan in &self.sampling_profiler_control { for chan in &self.sampling_profiler_control {
if let Err(e) = chan.send(SamplerControlMsg::Enable(rate)) { if let Err(e) = chan.send(SamplerControlMsg::Enable(rate, max_duration)) {
warn!("error communicating with sampling profiler: {}", e); warn!("error communicating with sampling profiler: {}", e);
} }
} }

View file

@ -494,6 +494,7 @@ pub trait BackgroundHangMonitor {
/// Messages to control the sampling profiler. /// Messages to control the sampling profiler.
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub enum SamplerControlMsg { pub enum SamplerControlMsg {
Enable(Duration), /// Enable the sampler, with a given sampling rate and max total sampling duration.
Enable(Duration, Duration),
Disable, Disable,
} }

View file

@ -778,8 +778,8 @@ pub enum ConstellationMsg {
ForwardEvent(PipelineId, CompositorEvent), ForwardEvent(PipelineId, CompositorEvent),
/// Requesting a change to the onscreen cursor. /// Requesting a change to the onscreen cursor.
SetCursor(Cursor), SetCursor(Cursor),
/// Enable the sampling profiler. /// Enable the sampling profiler, with a given sampling rate and max total sampling duration.
EnableProfiler(Duration), EnableProfiler(Duration, Duration),
/// Disable the sampling profiler. /// Disable the sampling profiler.
DisableProfiler, DisableProfiler,
} }

View file

@ -408,10 +408,10 @@ where
} }
}, },
WindowEvent::ToggleSamplingProfiler(rate) => { WindowEvent::ToggleSamplingProfiler(rate, max_duration) => {
self.profiler_enabled = !self.profiler_enabled; self.profiler_enabled = !self.profiler_enabled;
let msg = if self.profiler_enabled { let msg = if self.profiler_enabled {
ConstellationMsg::EnableProfiler(rate) ConstellationMsg::EnableProfiler(rate, max_duration)
} else { } else {
ConstellationMsg::DisableProfiler ConstellationMsg::DisableProfiler
}; };

View file

@ -121,8 +121,12 @@ impl Browser {
.ok() .ok()
.and_then(|s| s.parse().ok()) .and_then(|s| s.parse().ok())
.unwrap_or(10); .unwrap_or(10);
let duration = env::var("SAMPLING_DURATION")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(10);
self.event_queue.push(WindowEvent::ToggleSamplingProfiler( self.event_queue.push(WindowEvent::ToggleSamplingProfiler(
Duration::from_millis(rate))); Duration::from_millis(rate), Duration::from_secs(duration)));
}) })
.shortcut(Modifiers::CONTROL, Key::F9, || { .shortcut(Modifiers::CONTROL, Key::F9, || {
self.event_queue.push(WindowEvent::CaptureWebRender) self.event_queue.push(WindowEvent::CaptureWebRender)