Skip to content

Commit

Permalink
Heartbeats support for Android.
Browse files Browse the repository at this point in the history
Add debug option to enable heartbeats for all profiler categories.
  • Loading branch information
connorimes committed Oct 29, 2015
1 parent 965fbbd commit bb7e537
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
58 changes: 45 additions & 13 deletions components/profile/heartbeats.rs
Expand Up @@ -11,6 +11,8 @@ use std::env::var_os;
use std::error::Error;
use std::fs::File;
use std::mem;
use std::path::Path;
use util::opts;


static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None;
Expand Down Expand Up @@ -72,6 +74,7 @@ pub fn cleanup() {
}
}

/// Check if a heartbeat exists for the given category
pub fn is_heartbeat_enabled(category: &ProfilerCategory) -> bool {
unsafe {
HBS.map_or(false, |m| (*m).contains_key(category))
Expand All @@ -93,22 +96,51 @@ pub fn maybe_heartbeat(category: &ProfilerCategory,
}
}

/// Create a heartbeat if the correct environment variable is set
// TODO(cimes): Android doesn't really do environment variables. Need a better way to configure dynamically.

fn is_create_heartbeat(category: &ProfilerCategory) -> bool {
opts::get().profile_heartbeats || var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)).is_some()
}

fn open_heartbeat_log<P: AsRef<Path>>(name: P) -> Option<File> {
match File::create(name) {
Ok(f) => Some(f),
Err(e) => {
warn!("Failed to open heartbeat log: {}", Error::description(&e));
None
},
}
}

#[cfg(target_os = "android")]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
open_heartbeat_log(format!("/sdcard/servo/heartbeat-{:?}.log", category))
}

#[cfg(not(target_os = "android"))]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category)).and_then(|name| open_heartbeat_log(&name))
}

fn get_heartbeat_window_size(category: &ProfilerCategory) -> usize {
const WINDOW_SIZE_DEFAULT: usize = 1;
match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
Some(w) => match w.into_string() {
Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
_ => WINDOW_SIZE_DEFAULT,
},
None => WINDOW_SIZE_DEFAULT,
}
}

/// Possibly create a heartbeat
fn maybe_create_heartbeat(hbs: &mut HashMap<ProfilerCategory, Heartbeat>,
category: ProfilerCategory) {
static WINDOW_SIZE_DEFAULT: usize = 20;
if let Some(_) = var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)) {
if is_create_heartbeat(&category) {
// get optional log file
let logfile: Option<File> = var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category))
.and_then(|name| File::create(name).ok());
// get window size
let window_size: usize = match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
Some(w) => match w.into_string() {
Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
_ => WINDOW_SIZE_DEFAULT,
},
None => WINDOW_SIZE_DEFAULT,
};
let logfile: Option<File> = get_heartbeat_log(&category);
// window size
let window_size: usize = get_heartbeat_window_size(&category);
// create the heartbeat
match Heartbeat::new(window_size, Some(heartbeat_window_callback), logfile) {
Ok(hb) => {
Expand Down
13 changes: 12 additions & 1 deletion components/util/opts.rs
Expand Up @@ -121,6 +121,9 @@ pub struct Opts {
/// Periodically print out on which events script tasks spend their processing time.
pub profile_script_events: bool,

/// Enable all heartbeats for profiling.
pub profile_heartbeats: bool,

/// `None` to disable devtools or `Some` with a port number to start a server to listen to
/// remote Firefox devtools connections.
pub devtools_port: Option<u16>,
Expand Down Expand Up @@ -223,6 +226,9 @@ pub struct DebugOptions {
/// Profile which events script tasks spend their time on.
pub profile_script_events: bool,

/// Enable all heartbeats for profiling.
pub profile_heartbeats: bool,

/// Paint borders along layer and tile boundaries.
pub show_compositor_borders: bool,

Expand Down Expand Up @@ -286,6 +292,7 @@ impl DebugOptions {
"relayout-event" => debug_options.relayout_event = true,
"profile-tasks" => debug_options.profile_tasks = true,
"profile-script-events" => debug_options.profile_script_events = true,
"profile-heartbeats" => debug_options.profile_heartbeats = true,
"show-compositor-borders" => debug_options.show_compositor_borders = true,
"show-fragment-borders" => debug_options.show_fragment_borders = true,
"show-parallel-paint" => debug_options.show_parallel_paint = true,
Expand Down Expand Up @@ -325,6 +332,8 @@ pub fn print_debug_usage(app: &str) -> ! {
print_option("dump-layer-tree", "Print the layer tree whenever it changes.");
print_option("relayout-event", "Print notifications when there is a relayout.");
print_option("profile-tasks", "Instrument each task, writing the output to a file.");
print_option("profile-script-events", "Enable profiling of script-related events.");
print_option("profile-heartbeats", "Enable heartbeats for all task categories.");
print_option("show-compositor-borders", "Paint borders along layer and tile boundaries.");
print_option("show-fragment-borders", "Paint borders along fragment boundaries.");
print_option("show-parallel-paint", "Overlay tiles with colors showing which thread painted them.");
Expand All @@ -336,10 +345,10 @@ pub fn print_debug_usage(app: &str) -> ! {
print_option("disable-share-style-cache",
"Disable the style sharing cache.");
print_option("parallel-display-list-building", "Build display lists in parallel.");
print_option("convert-mouse-to-touch", "Send touch events instead of mouse events");
print_option("replace-surrogates", "Replace unpaires surrogates in DOM strings with U+FFFD. \
See https://github.com/servo/servo/issues/6564");
print_option("gc-profile", "Log GC passes and their durations.");
print_option("convert-mouse-to-touch", "Send touch events instead of mouse events");

println!("");

Expand Down Expand Up @@ -433,6 +442,7 @@ pub fn default_opts() -> Opts {
validate_display_list_geometry: false,
profile_tasks: false,
profile_script_events: false,
profile_heartbeats: false,
sniff_mime_types: false,
disable_share_style_cache: false,
parallel_display_list_building: false,
Expand Down Expand Up @@ -620,6 +630,7 @@ pub fn from_cmdline_args(args: &[String]) {
bubble_inline_sizes_separately: bubble_inline_sizes_separately,
profile_tasks: debug_options.profile_tasks,
profile_script_events: debug_options.profile_script_events,
profile_heartbeats: debug_options.profile_heartbeats,
trace_layout: debug_options.trace_layout,
devtools_port: devtools_port,
webdriver_port: webdriver_port,
Expand Down

0 comments on commit bb7e537

Please sign in to comment.