diff options
author | Gregory Terzian <gterzian@users.noreply.github.com> | 2018-09-11 15:49:47 +0800 |
---|---|---|
committer | Gregory Terzian <gterzian@users.noreply.github.com> | 2018-11-26 14:15:33 +0800 |
commit | 4eb785cdc0446539bf5e7eb66bf7ad46ba5705dd (patch) | |
tree | 3703ffe374141ff2816b1b3adf6c54ec1bdcf722 /components/script/script_thread.rs | |
parent | 7c65505df3fff47f43062da20088113631ed9ae0 (diff) | |
download | servo-4eb785cdc0446539bf5e7eb66bf7ad46ba5705dd.tar.gz servo-4eb785cdc0446539bf5e7eb66bf7ad46ba5705dd.zip |
introduce a background-hang-monitor:
Mac-Os implementation of a thread sampler,
Linux and Windows skeleton implementations.
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r-- | components/script/script_thread.rs | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 21c87d772e9..ee06f672bc3 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -101,7 +101,11 @@ use js::jsapi::{JSTracer, SetWindowProxyClass}; use js::jsval::UndefinedValue; use metrics::{PaintTimeMetrics, MAX_TASK_NS}; use mime::{self, Mime}; +use msg::constellation_msg::{ + BackgroundHangMonitor, BackgroundHangMonitorRegister, ScriptHangAnnotation, +}; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId}; +use msg::constellation_msg::{HangAnnotation, MonitoredComponentId, MonitoredComponentType}; use msg::constellation_msg::{PipelineNamespace, TopLevelBrowsingContextId}; use net_traits::image_cache::{ImageCache, PendingImageResponse}; use net_traits::request::{CredentialsMode, Destination, RedirectMode, RequestInit}; @@ -140,7 +144,7 @@ use std::rc::Rc; use std::result::Result; use std::sync::Arc; use std::thread; -use std::time::SystemTime; +use std::time::{Duration, SystemTime}; use style::thread_state::{self, ThreadState}; use time::{at_utc, get_time, precise_time_ns, Timespec}; use url::percent_encoding::percent_decode; @@ -483,6 +487,9 @@ unsafe_no_jsmanaged_fields!(RefCell<IncompleteParserContexts>); unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>); +unsafe_no_jsmanaged_fields!(BackgroundHangMonitorRegister); +unsafe_no_jsmanaged_fields!(BackgroundHangMonitor); + #[derive(JSTraceable)] // ScriptThread instances are rooted on creation, so this is okay #[allow(unrooted_must_root)] @@ -511,6 +518,11 @@ pub struct ScriptThread { /// A queue of tasks to be executed in this script-thread. task_queue: TaskQueue<MainThreadScriptMsg>, + /// A handle to register associated layout threads for hang-monitoring. + background_hang_monitor_register: Box<BackgroundHangMonitorRegister>, + /// The dedicated means of communication with the background-hang-monitor for this script-thread. + background_hang_monitor: Box<BackgroundHangMonitor>, + /// A channel to hand out to script thread-based entities that need to be able to enqueue /// events in the event queue. chan: MainThreadScriptChan, @@ -668,6 +680,7 @@ impl ScriptThreadFactory for ScriptThread { let opener = state.opener; let mem_profiler_chan = state.mem_profiler_chan.clone(); let window_size = state.window_size; + let script_thread = ScriptThread::new(state, script_port, script_chan.clone()); SCRIPT_THREAD_ROOT.with(|root| { @@ -1019,6 +1032,12 @@ impl ScriptThread { let task_queue = TaskQueue::new(port, chan.clone()); + let background_hang_monitor = state.background_hang_monitor_register.register_component( + MonitoredComponentId(state.id, MonitoredComponentType::Script), + Duration::from_millis(1000), + Duration::from_millis(5000), + ); + ScriptThread { documents: DomRefCell::new(Documents::new()), window_proxies: DomRefCell::new(HashMap::new()), @@ -1036,6 +1055,9 @@ impl ScriptThread { task_queue, + background_hang_monitor_register: state.background_hang_monitor_register, + background_hang_monitor, + chan: MainThreadScriptChan(chan.clone()), dom_manipulation_task_sender: boxed_script_sender.clone(), media_element_task_sender: chan.clone(), @@ -1129,6 +1151,9 @@ impl ScriptThread { // Store new resizes, and gather all other events. let mut sequential = vec![]; + // Notify the background-hang-monitor we are waiting for an event. + self.background_hang_monitor.notify_wait(); + // Receive at least one message so we don't spinloop. debug!("Waiting for event."); let mut event = select! { @@ -1325,6 +1350,47 @@ impl ScriptThread { } } + fn notify_activity_to_hang_monitor(&self, category: &ScriptThreadEventCategory) { + let hang_annotation = match category { + ScriptThreadEventCategory::AttachLayout => ScriptHangAnnotation::AttachLayout, + ScriptThreadEventCategory::ConstellationMsg => ScriptHangAnnotation::ConstellationMsg, + ScriptThreadEventCategory::DevtoolsMsg => ScriptHangAnnotation::DevtoolsMsg, + ScriptThreadEventCategory::DocumentEvent => ScriptHangAnnotation::DocumentEvent, + ScriptThreadEventCategory::DomEvent => ScriptHangAnnotation::DomEvent, + ScriptThreadEventCategory::FileRead => ScriptHangAnnotation::FileRead, + ScriptThreadEventCategory::FormPlannedNavigation => { + ScriptHangAnnotation::FormPlannedNavigation + }, + ScriptThreadEventCategory::HistoryEvent => ScriptHangAnnotation::HistoryEvent, + ScriptThreadEventCategory::ImageCacheMsg => ScriptHangAnnotation::ImageCacheMsg, + ScriptThreadEventCategory::InputEvent => ScriptHangAnnotation::InputEvent, + ScriptThreadEventCategory::NetworkEvent => ScriptHangAnnotation::NetworkEvent, + ScriptThreadEventCategory::Resize => ScriptHangAnnotation::Resize, + ScriptThreadEventCategory::ScriptEvent => ScriptHangAnnotation::ScriptEvent, + ScriptThreadEventCategory::SetScrollState => ScriptHangAnnotation::SetScrollState, + ScriptThreadEventCategory::SetViewport => ScriptHangAnnotation::SetViewport, + ScriptThreadEventCategory::StylesheetLoad => ScriptHangAnnotation::StylesheetLoad, + ScriptThreadEventCategory::TimerEvent => ScriptHangAnnotation::TimerEvent, + ScriptThreadEventCategory::UpdateReplacedElement => { + ScriptHangAnnotation::UpdateReplacedElement + }, + ScriptThreadEventCategory::WebSocketEvent => ScriptHangAnnotation::WebSocketEvent, + ScriptThreadEventCategory::WorkerEvent => ScriptHangAnnotation::WorkerEvent, + ScriptThreadEventCategory::WorkletEvent => ScriptHangAnnotation::WorkletEvent, + ScriptThreadEventCategory::ServiceWorkerEvent => { + ScriptHangAnnotation::ServiceWorkerEvent + }, + ScriptThreadEventCategory::EnterFullscreen => ScriptHangAnnotation::EnterFullscreen, + ScriptThreadEventCategory::ExitFullscreen => ScriptHangAnnotation::ExitFullscreen, + ScriptThreadEventCategory::WebVREvent => ScriptHangAnnotation::WebVREvent, + ScriptThreadEventCategory::PerformanceTimelineTask => { + ScriptHangAnnotation::PerformanceTimelineTask + }, + }; + self.background_hang_monitor + .notify_activity(HangAnnotation::Script(hang_annotation)); + } + fn message_to_pipeline(&self, msg: &MixedMessage) -> Option<PipelineId> { use script_traits::ConstellationControlMsg::*; match *msg { @@ -1399,6 +1465,7 @@ impl ScriptThread { where F: FnOnce() -> R, { + self.notify_activity_to_hang_monitor(&category); let start = precise_time_ns(); let value = if opts::get().profile_script_events { let profiler_cat = match category { @@ -1855,6 +1922,7 @@ impl ScriptThread { is_parent: false, layout_pair: layout_pair, pipeline_port: pipeline_port, + background_hang_monitor_register: self.background_hang_monitor_register.clone(), constellation_chan: self.layout_to_constellation_chan.clone(), script_chan: self.control_chan.clone(), image_cache: self.image_cache.clone(), |