Permalink
Browse files

Issue servo#7029 Early sketch of Telemetry in Servo

Telemetry histograms can be declared in any module. I am planning to add a macro to make the work a bit nicer, and possibly to generate Histograms.json automatically.
  • Loading branch information...
Yoric committed Oct 14, 2015
1 parent b7f5969 commit 70f90d02b2e39f5759953b5620b8067176b58161
@@ -50,6 +50,8 @@ use time::{precise_time_ns, precise_time_s};
use url::Url;
use util::geometry::{PagePx, ScreenPx, ViewportPx};
use util::opts;
use util::telemetry::*;
use util::telemetry;
use util::print_tree::PrintTree;
use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
@@ -59,6 +61,22 @@ const BUFFER_MAP_SIZE: usize = 10000000;
const MAX_ZOOM: f32 = 8.0;
const MIN_ZOOM: f32 = 0.1;
///
/// # Histograms
///
/// In the future, this section will probably be generated by a macro.
///
pub static COUNT_SYNC_REPAINTS : StaticCell<Count> = StaticCell::new();
fn telemetry_init(telemetry: &telemetry::Service) -> Vec<CleanGuard<'static>> {
let mut guards = Vec::new();
guards.push(COUNT_SYNC_REPAINTS.init(Count::new(&telemetry, "COUNT_SYNC_REPAINTS".to_owned())));
guards
}
/// Holds the state when running reftests that determines when it is
/// safe to save the output image.
#[derive(Copy, Clone, PartialEq)]
@@ -166,6 +184,10 @@ pub struct IOCompositor<Window: WindowMethods> {
/// Pipeline IDs of subpages that the compositor has seen in a layer tree but which have not
/// yet been painted.
pending_subpages: HashSet<PipelineId>,
_telemetry_guards: Vec<CleanGuard<'static>>,
count_sync_repaints: Box<Count>,
}
pub struct ScrollEvent {
@@ -255,7 +277,8 @@ pub fn reporter_name() -> String {
impl<Window: WindowMethods> IOCompositor<Window> {
fn new(window: Rc<Window>, state: InitialCompositorState)
-> IOCompositor<Window> {
-> IOCompositor<Window>
{
// Register this thread as a memory reporter, via its own channel.
let (reporter_sender, reporter_receiver) = ipc::channel().unwrap();
let compositor_proxy_for_memory_reporter = state.sender.clone_compositor_proxy();
@@ -275,6 +298,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
None => CompositeTarget::Window
};
let native_display = window.native_display();
let _telemetry_guards = telemetry_init(&telemetry::TELEMETRY.get().unwrap());
let count_sync_repaints = COUNT_SYNC_REPAINTS.get().unwrap();
IOCompositor {
window: window,
native_display: native_display,
@@ -310,6 +335,8 @@ impl<Window: WindowMethods> IOCompositor<Window> {
ready_to_save_state: ReadyState::Unknown,
surface_map: SurfaceMap::new(BUFFER_MAP_SIZE),
pending_subpages: HashSet::new(),
_telemetry_guards: _telemetry_guards,
count_sync_repaints: count_sync_repaints,
}
}
@@ -1855,6 +1882,7 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
///
/// This is used when resizing the window.
fn repaint_synchronously(&mut self) {
self.count_sync_repaints.record(1);
while self.shutdown_state != ShutdownState::ShuttingDown {
let msg = self.port.recv_compositor_msg();
let received_new_buffers = match msg {
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(iter_cmp)]
#![feature(slice_bytes)]
#![feature(vec_push_all)]

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
@@ -132,3 +132,4 @@ env_logger = "0.3"
time = "0.1.12"
bitflags = "0.3"
libc = "0.1"
telemetry = "0.1.1"
@@ -76,6 +76,7 @@ use std::borrow::Borrow;
use std::rc::Rc;
use std::sync::mpsc::Sender;
use util::opts;
pub use util::telemetry;
pub use _util as util;
pub use export::canvas;
@@ -98,6 +99,7 @@ pub use export::script_traits;
pub use export::style;
pub use export::url;
pub struct Browser {
compositor: Box<CompositorEventListener + 'static>,
}
@@ -16,6 +16,7 @@
//! [glutin]: https://github.com/tomaka/glutin
#![feature(start)]
#![feature(const_fn)]
#[cfg(target_os = "android")]
#[macro_use]
@@ -31,16 +32,50 @@ use servo::Browser;
use servo::compositing::windowing::WindowEvent;
use servo::net_traits::hosts;
use servo::util::opts;
use servo::util::telemetry::*;
use servo::util::telemetry;
#[cfg(target_os = "android")]
use std::borrow::ToOwned;
use std::rc::Rc;
///
/// # Histograms
///
/// In the future, this section will probably be generated by a macro.
///
/// Set immediately.
static HAS_STARTED : StaticCell<Flag> = StaticCell::new();
/// Set at the end of `main()`.
static HAS_SHUTDOWN : StaticCell<Flag> = StaticCell::new();
fn telemetry_init(telemetry: &telemetry::Service) -> Vec<CleanGuard<'static>> {
let mut guards = Vec::new();
// Initialize the two local histograms.
// In this specific case, we could do something simpler.
guards.push(HAS_STARTED.init(Flag::new(&telemetry, "HAS_STARTED".to_owned())));
guards.push(HAS_SHUTDOWN.init(Flag::new(&telemetry, "HAS_SHUTDOWN".to_owned())));
guards
}
fn main() {
env_logger::init().unwrap();
// Parse the command line options and store them globally
opts::from_cmdline_args(&*args());
// Initialize telemetry.
let mut _telemetry_guards = Vec::new();
_telemetry_guards.push(telemetry::init(opts::get().is_telemetry_enabled));
let telemetry = telemetry::TELEMETRY.get().unwrap();
_telemetry_guards.append(&mut telemetry_init(&telemetry));
HAS_STARTED.get().unwrap().record(());
setup_logging();
// Possibly interpret the `HOST_FILE` environment variable
@@ -75,6 +110,12 @@ fn main() {
};
maybe_unregister_glutin_resize_handler(&window);
HAS_SHUTDOWN.get().unwrap().record(());
if opts::get().is_telemetry_enabled {
telemetry::dump();
}
}
fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
@@ -59,3 +59,5 @@ string_cache = "0.1"
lazy_static = "0.1"
getopts = "0.2.11"
hyper = "0.6"
telemetry = "0.1.1"
atomic_cell = "0.1.0"
@@ -4,6 +4,7 @@
#![feature(alloc)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(custom_derive)]
#![feature(fnbox)]
@@ -73,6 +74,7 @@ pub mod task_state;
pub mod taskpool;
pub mod tid;
pub mod vec;
pub mod telemetry;
pub mod workqueue;
pub fn breakpoint() {
@@ -173,6 +173,11 @@ pub struct Opts {
/// Do not use native titlebar
pub no_native_titlebar: bool,
/// `true` if we wish to capture measurements through Telemetry,
/// `false` otherwise. Telemetry measurements are dumped at the
/// end of execution.
pub is_telemetry_enabled: bool,
}
fn print_usage(app: &str, opts: &Options) {
@@ -424,6 +429,7 @@ pub fn default_opts() -> Opts {
parallel_display_list_building: false,
exit_after_load: false,
no_native_titlebar: false,
is_telemetry_enabled: false,
}
}
@@ -465,7 +471,7 @@ pub fn from_cmdline_args(args: &[String]) {
opts.optmulti("", "pref",
"A preference to set to enable", "dom.mozbrowser.enabled");
opts.optflag("b", "no-native-titlebar", "Do not use native titlebar");
opts.optflag("", "enable-telemetry", "Collect data through Telemetry");
let opt_match = match opts.parse(args) {
Ok(m) => m,
Err(f) => args_fail(&f.to_string()),
@@ -630,6 +636,7 @@ pub fn from_cmdline_args(args: &[String]) {
parallel_display_list_building: debug_options.parallel_display_list_building,
exit_after_load: opt_match.opt_present("x"),
no_native_titlebar: opt_match.opt_present("b"),
is_telemetry_enabled: opt_match.opt_present("enable-telemetry"),
};
set_defaults(opts);
@@ -0,0 +1,42 @@
//!
//! Telemetry histograms.
//!
//! In future versions, this file may be generated by a
//! Histograms.json, as in Gecko. Or maybe it will be the opposite and
//! Histograms.json will be generated from this file.
//!
use std::sync::Arc;
use std::sync::mpsc::channel;
extern crate telemetry;
pub use self::telemetry::Service;
pub use self::telemetry::plain::*;
extern crate atomic_cell;
pub use self::atomic_cell::StaticCell;
pub use self::atomic_cell::CleanGuard;
///
/// The shared instance of the telemetry service.
///
pub static TELEMETRY: StaticCell<Arc<Service>> = StaticCell::new();
pub fn init(is_active: bool) -> CleanGuard<'static>{
TELEMETRY.init(Arc::new(Service::new(is_active)))
}
pub fn dump() {
let service = TELEMETRY.get().unwrap();
let (sender, receiver) = channel();
// Collect plain histograms
service.to_json(telemetry::Subset::AllPlain, telemetry::SerializationFormat::SimpleJson, sender.clone());
let plain = receiver.recv().unwrap();
// Collect keyed histograms
service.to_json(telemetry::Subset::AllKeyed, telemetry::SerializationFormat::SimpleJson, sender.clone());
let keyed = receiver.recv().unwrap();
print!("{}\n", plain.pretty());
print!("{}\n", keyed.pretty());
}

0 comments on commit 70f90d0

Please sign in to comment.