зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #8253 - Heartbeats and energy profiling support for Android (from connorimes:android-energy-profiling); r=mbrubeck
Source-Repo: https://github.com/servo/servo Source-Revision: f9d79600c9399c6f804cfdce4a42fc118a1bdb47
This commit is contained in:
Родитель
741243bea5
Коммит
a6521e4324
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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) => {
|
||||
|
|
|
@ -19,7 +19,7 @@ features = [ "serde_serialization" ]
|
|||
|
||||
[dependencies.energymon]
|
||||
git = "https://github.com/energymon/energymon-rust.git"
|
||||
rev = "67f74732ac"
|
||||
rev = "eba1d8a"
|
||||
optional = true
|
||||
|
||||
[dependencies.energy-monitor]
|
||||
|
|
|
@ -36,8 +36,8 @@ mod energymon {
|
|||
|
||||
static mut EM: Option<*mut EnergyMon> = None;
|
||||
|
||||
/// Read energy from the energy monitor, otherwise return 0.
|
||||
pub fn read_energy_uj() -> u64 {
|
||||
fn init() {
|
||||
// can't use lazy_static macro for EM (no Sync trait for EnergyMon)
|
||||
static ONCE: Once = ONCE_INIT;
|
||||
ONCE.call_once(|| {
|
||||
if let Ok(em) = EnergyMon::new() {
|
||||
|
@ -47,7 +47,11 @@ mod energymon {
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Read energy from the energy monitor, otherwise return 0.
|
||||
pub fn read_energy_uj() -> u64 {
|
||||
init();
|
||||
unsafe {
|
||||
// EnergyMon implementations of EnergyMonitor always return a value
|
||||
EM.map_or(0, |em| (*em).read_uj().unwrap())
|
||||
|
@ -55,6 +59,7 @@ mod energymon {
|
|||
}
|
||||
|
||||
pub fn get_min_interval_ms() -> u32 {
|
||||
init();
|
||||
unsafe {
|
||||
EM.map_or(0, |em| ((*em).interval_us() as f64 / 1000.0).ceil() as u32)
|
||||
}
|
||||
|
|
|
@ -474,18 +474,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "energymon"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/energymon/energymon-rust.git?rev=67f74732ac#67f74732ac0acc682659f7e81836155a32188fd0"
|
||||
source = "git+https://github.com/energymon/energymon-rust.git?rev=eba1d8a#eba1d8a7256b710230ea2c1b26525b88bfcb529d"
|
||||
dependencies = [
|
||||
"energy-monitor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"energymon-default-sys 0.1.0 (git+https://github.com/energymon/energymon-default-sys.git)",
|
||||
"energymon-sys 0.1.0 (git+https://github.com/energymon/energymon-sys.git)",
|
||||
"energymon-default-sys 0.1.0 (git+https://github.com/energymon/energymon-sys.git)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "energymon-default-sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/energymon/energymon-default-sys.git#82dd2f6762b492ced15d8446b70569778200c287"
|
||||
source = "git+https://github.com/energymon/energymon-sys.git#82756eee725db3ccb658f14857947a0260743d4d"
|
||||
dependencies = [
|
||||
"energymon-sys 0.1.0 (git+https://github.com/energymon/energymon-sys.git)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -495,7 +494,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "energymon-sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/energymon/energymon-sys.git#6306f70e5d5c824fa168e43521385798fd1b890b"
|
||||
source = "git+https://github.com/energymon/energymon-sys.git#82756eee725db3ccb658f14857947a0260743d4d"
|
||||
dependencies = [
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1436,7 +1435,7 @@ name = "profile_traits"
|
|||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"energy-monitor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"energymon 0.1.0 (git+https://github.com/energymon/energymon-rust.git?rev=67f74732ac)",
|
||||
"energymon 0.1.0 (git+https://github.com/energymon/energymon-rust.git?rev=eba1d8a)",
|
||||
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||
"plugins 0.0.1",
|
||||
"serde 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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.");
|
||||
|
@ -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!("");
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче