mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
profile: Make the time and memory profilers run over IPC.
Uses the `Router` abstraction inside `ipc-channel` to avoid spawning new threads.
This commit is contained in:
parent
ed1b6a3513
commit
f10c076180
19 changed files with 212 additions and 168 deletions
|
@ -7,7 +7,12 @@ authors = ["The Servo Project Developers"]
|
|||
name = "profile_traits"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.ipc-channel]
|
||||
git = "https://github.com/pcwalton/ipc-channel"
|
||||
|
||||
[dependencies]
|
||||
serde = "0.4"
|
||||
serde_macros = "0.4"
|
||||
time = "0.1.12"
|
||||
url = "0.2.36"
|
||||
|
||||
|
|
|
@ -6,5 +6,12 @@
|
|||
//! rest of Servo. These APIs are here instead of in `profile` so that these
|
||||
//! modules won't have to depend on `profile`.
|
||||
|
||||
#![feature(custom_derive, plugin)]
|
||||
#![plugin(serde_macros)]
|
||||
|
||||
extern crate ipc_channel;
|
||||
extern crate serde;
|
||||
|
||||
pub mod mem;
|
||||
pub mod time;
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use std::sync::mpsc::Sender;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
|
||||
/// Front-end representation of the profiler used to communicate with the
|
||||
/// profiler.
|
||||
#[derive(Clone)]
|
||||
pub struct ProfilerChan(pub Sender<ProfilerMsg>);
|
||||
pub struct ProfilerChan(pub IpcSender<ProfilerMsg>);
|
||||
|
||||
impl ProfilerChan {
|
||||
/// Send `msg` on this `Sender`.
|
||||
/// Send `msg` on this `IpcSender`.
|
||||
///
|
||||
/// Panics if the send fails.
|
||||
pub fn send(&self, msg: ProfilerMsg) {
|
||||
|
@ -24,6 +24,7 @@ impl ProfilerChan {
|
|||
}
|
||||
|
||||
/// A single memory-related measurement.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Report {
|
||||
/// The identifying path for this report.
|
||||
pub path: Vec<String>,
|
||||
|
@ -33,11 +34,11 @@ pub struct Report {
|
|||
}
|
||||
|
||||
/// A channel through which memory reports can be sent.
|
||||
#[derive(Clone)]
|
||||
pub struct ReportsChan(pub Sender<Vec<Report>>);
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct ReportsChan(pub IpcSender<Vec<Report>>);
|
||||
|
||||
impl ReportsChan {
|
||||
/// Send `report` on this `Sender`.
|
||||
/// Send `report` on this `IpcSender`.
|
||||
///
|
||||
/// Panics if the send fails.
|
||||
pub fn send(&self, report: Vec<Report>) {
|
||||
|
@ -46,13 +47,30 @@ impl ReportsChan {
|
|||
}
|
||||
}
|
||||
|
||||
/// A memory reporter is capable of measuring some data structure of interest. Because it needs to
|
||||
/// be passed to and registered with the Profiler, it's typically a "small" (i.e. easily cloneable)
|
||||
/// value that provides access to a "large" data structure, e.g. a channel that can inject a
|
||||
/// request for measurements into the event queue associated with the "large" data structure.
|
||||
pub trait Reporter {
|
||||
/// The protocol used to send reporter requests.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct ReporterRequest {
|
||||
/// The channel on which reports are to be sent.
|
||||
pub reports_channel: ReportsChan,
|
||||
}
|
||||
|
||||
/// A memory reporter is capable of measuring some data structure of interest. It's structured as
|
||||
/// an IPC sender that a `ReporterRequest` in transmitted over. `ReporterRequest` objects in turn
|
||||
/// encapsulate the channel on which the memory profiling information is to be sent.
|
||||
///
|
||||
/// In many cases, clients construct `Reporter` objects by creating an IPC sender/receiver pair and
|
||||
/// registering the receiving end with the router so that messages from the memory profiler end up
|
||||
/// injected into the client's event loop.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Reporter(pub IpcSender<ReporterRequest>);
|
||||
|
||||
impl Reporter {
|
||||
/// Collect one or more memory reports. Returns true on success, and false on failure.
|
||||
fn collect_reports(&self, reports_chan: ReportsChan) -> bool;
|
||||
pub fn collect_reports(&self, reports_chan: ReportsChan) {
|
||||
self.0.send(ReporterRequest {
|
||||
reports_channel: reports_chan,
|
||||
}).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// An easy way to build a path for a report.
|
||||
|
@ -65,11 +83,12 @@ macro_rules! path {
|
|||
}
|
||||
|
||||
/// Messages that can be sent to the memory profiler thread.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum ProfilerMsg {
|
||||
/// Register a Reporter with the memory profiler. The String is only used to identify the
|
||||
/// reporter so it can be unregistered later. The String must be distinct from that used by any
|
||||
/// other registered reporter otherwise a panic will occur.
|
||||
RegisterReporter(String, Box<Reporter + Send>),
|
||||
RegisterReporter(String, Reporter),
|
||||
|
||||
/// Unregister a Reporter with the memory profiler. The String must match the name given when
|
||||
/// the reporter was registered. If the String does not match the name of a registered reporter
|
||||
|
@ -82,3 +101,4 @@ pub enum ProfilerMsg {
|
|||
/// Tells the memory profiler to shut down.
|
||||
Exit,
|
||||
}
|
||||
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
extern crate time as std_time;
|
||||
extern crate url;
|
||||
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use self::std_time::precise_time_ns;
|
||||
use self::url::Url;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
|
||||
#[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Deserialize, Serialize)]
|
||||
pub struct TimerMetadata {
|
||||
pub url: String,
|
||||
pub iframe: bool,
|
||||
pub incremental: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ProfilerChan(pub Sender<ProfilerMsg>);
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct ProfilerChan(pub IpcSender<ProfilerMsg>);
|
||||
|
||||
impl ProfilerChan {
|
||||
pub fn send(&self, msg: ProfilerMsg) {
|
||||
|
@ -26,7 +26,7 @@ impl ProfilerChan {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub enum ProfilerMsg {
|
||||
/// Normal message used for reporting time
|
||||
Time((ProfilerCategory, Option<TimerMetadata>), f64),
|
||||
|
@ -37,7 +37,7 @@ pub enum ProfilerMsg {
|
|||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
|
||||
#[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Deserialize, Serialize)]
|
||||
pub enum ProfilerCategory {
|
||||
Compositing,
|
||||
LayoutPerform,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue