From 491851610eb1371a8ef8444157e72a273df9df99 Mon Sep 17 00:00:00 2001 From: Guro Bokum Date: Tue, 14 Apr 2015 20:24:00 +0700 Subject: [PATCH] Send high resolution millisecond timestamps in timeline markers #5665 --- components/devtools/actor.rs | 10 ++++- components/devtools/actors/timeline.rs | 60 ++++++++++++++++++-------- components/devtools_traits/lib.rs | 4 +- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/components/devtools/actor.rs b/components/devtools/actor.rs index 125080328f0d..1fdd2af5c14a 100644 --- a/components/devtools/actor.rs +++ b/components/devtools/actor.rs @@ -4,6 +4,7 @@ /// General actor system infrastructure. +use rustc_serialize::json; use std::any::{Any, TypeId}; use std::collections::HashMap; use std::cell::{Cell, RefCell}; @@ -11,7 +12,7 @@ use std::mem::{replace, transmute}; use std::net::TcpStream; use std::raw::TraitObject; use std::sync::{Arc, Mutex}; -use rustc_serialize::json; +use time::PreciseTime; /// A common trait for all devtools actors that encompasses an immutable name /// and the ability to process messages that are directed to particular actors. @@ -82,6 +83,7 @@ pub struct ActorRegistry { script_actors: RefCell>, shareable: Option>>, next: Cell, + start_stamp: PreciseTime, } impl ActorRegistry { @@ -94,6 +96,7 @@ impl ActorRegistry { script_actors: RefCell::new(HashMap::new()), shareable: None, next: Cell::new(0), + start_stamp: PreciseTime::now(), } } @@ -115,6 +118,11 @@ impl ActorRegistry { self.shareable.as_ref().unwrap().clone() } + /// Get start stamp when registry was started + pub fn get_start_stamp(&self) -> PreciseTime { + self.start_stamp.clone() + } + pub fn register_script_actor(&self, script_id: String, actor: String) { println!("registering {} ({})", actor, script_id); let mut script_actors = self.script_actors.borrow_mut(); diff --git a/components/devtools/actors/timeline.rs b/components/devtools/actors/timeline.rs index 94ab37ce3c72..6ea92626ae3c 100644 --- a/components/devtools/actors/timeline.rs +++ b/components/devtools/actors/timeline.rs @@ -4,7 +4,7 @@ use core::iter::FromIterator; use msg::constellation_msg::PipelineId; -use rustc_serialize::json; +use rustc_serialize::{json, Encoder, Encodable}; use std::cell::RefCell; use std::collections::{HashMap, VecDeque}; use std::net::TcpStream; @@ -12,7 +12,7 @@ use std::old_io::timer::sleep; use std::sync::{Arc, Mutex}; use std::time::duration::Duration; use std::sync::mpsc::{channel, Sender, Receiver}; -use time::precise_time_ns; +use time::PreciseTime; use actor::{Actor, ActorRegistry}; use actors::memory::{MemoryActor, TimelineMemoryReply}; @@ -40,6 +40,7 @@ struct Emitter { stream: TcpStream, markers: Vec, registry: Arc>, + start_stamp: PreciseTime, framerate_actor: Option, memory_actor: Option, @@ -54,20 +55,20 @@ struct IsRecordingReply { #[derive(RustcEncodable)] struct StartReply { from: String, - value: u64 + value: HighResolutionStamp, } #[derive(RustcEncodable)] struct StopReply { from: String, - value: u64 + value: HighResolutionStamp, } #[derive(RustcEncodable)] struct TimelineMarkerReply { name: String, - start: u64, - end: u64, + start: HighResolutionStamp, + end: HighResolutionStamp, stack: Option>, endStack: Option>, } @@ -77,14 +78,14 @@ struct MarkersEmitterReply { __type__: String, markers: Vec, from: String, - endTime: u64, + endTime: HighResolutionStamp, } #[derive(RustcEncodable)] struct MemoryEmitterReply { __type__: String, from: String, - delta: u64, + delta: HighResolutionStamp, measurement: TimelineMemoryReply, } @@ -92,10 +93,30 @@ struct MemoryEmitterReply { struct FramerateEmitterReply { __type__: String, from: String, - delta: u64, + delta: HighResolutionStamp, timestamps: Vec, } +/// HighResolutionStamp is struct that contains duration in milliseconds +/// with accuracy to microsecond that shows how much time has passed since +/// actor registry inited +/// analog https://w3c.github.io/hr-time/#sec-DOMHighResTimeStamp +struct HighResolutionStamp(f64); + +impl HighResolutionStamp { + fn new(start_stamp: PreciseTime, time: PreciseTime) -> HighResolutionStamp { + let duration = start_stamp.to(time).num_microseconds() + .expect("Too big duration in microseconds"); + HighResolutionStamp(duration as f64 / 1000 as f64) + } +} + +impl Encodable for HighResolutionStamp { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + self.0.encode(s) + } +} + static DEFAULT_TIMELINE_DATA_PULL_TIMEOUT: usize = 200; //ms impl TimelineActor { @@ -233,6 +254,7 @@ impl Actor for TimelineActor { } let emitter = Emitter::new(self.name(), registry.get_shareable(), + registry.get_start_stamp(), stream.try_clone().unwrap(), self.memory_actor.borrow().clone(), self.framerate_actor.borrow().clone()); @@ -241,7 +263,8 @@ impl Actor for TimelineActor { let msg = StartReply { from: self.name(), - value: precise_time_ns(), + value: HighResolutionStamp::new(registry.get_start_stamp(), + PreciseTime::now()), }; stream.write_json_packet(&msg); true @@ -250,7 +273,8 @@ impl Actor for TimelineActor { "stop" => { let msg = StopReply { from: self.name(), - value: precise_time_ns() + value: HighResolutionStamp::new(registry.get_start_stamp(), + PreciseTime::now()), }; stream.write_json_packet(&msg); @@ -289,6 +313,7 @@ impl Actor for TimelineActor { impl Emitter { pub fn new(name: String, registry: Arc>, + start_stamp: PreciseTime, stream: TcpStream, memory_actor_name: Option, framerate_actor_name: Option) -> Emitter { @@ -298,6 +323,7 @@ impl Emitter { stream: stream, markers: Vec::new(), registry: registry, + start_stamp: start_stamp, framerate_actor: framerate_actor_name, memory_actor: memory_actor_name, @@ -307,20 +333,20 @@ impl Emitter { fn add_marker(&mut self, start_payload: TimelineMarker, end_payload: TimelineMarker) -> () { self.markers.push(TimelineMarkerReply { name: start_payload.name, - start: start_payload.time, - end: end_payload.time, + start: HighResolutionStamp::new(self.start_stamp, start_payload.time), + end: HighResolutionStamp::new(self.start_stamp, end_payload.time), stack: start_payload.stack, endStack: end_payload.stack, }); } fn send(&mut self) -> () { - let end_time = precise_time_ns(); + let end_time = PreciseTime::now(); let reply = MarkersEmitterReply { __type__: "markers".to_string(), markers: Vec::from_iter(self.markers.drain()), from: self.from.clone(), - endTime: end_time, + endTime: HighResolutionStamp::new(self.start_stamp, end_time), }; self.stream.write_json_packet(&reply); @@ -331,7 +357,7 @@ impl Emitter { let framerateReply = FramerateEmitterReply { __type__: "framerate".to_string(), from: framerate_actor.name(), - delta: end_time, + delta: HighResolutionStamp::new(self.start_stamp, end_time), timestamps: framerate_actor.take_pending_ticks(), }; self.stream.write_json_packet(&framerateReply); @@ -343,7 +369,7 @@ impl Emitter { let memoryReply = MemoryEmitterReply { __type__: "memory".to_string(), from: memory_actor.name(), - delta: end_time, + delta: HighResolutionStamp::new(self.start_stamp, end_time), measurement: memory_actor.measure(), }; self.stream.write_json_packet(&memoryReply); diff --git a/components/devtools_traits/lib.rs b/components/devtools_traits/lib.rs index 851a8e6da1b6..c77fb34c6ee5 100644 --- a/components/devtools_traits/lib.rs +++ b/components/devtools_traits/lib.rs @@ -96,7 +96,7 @@ pub enum TracingMetadata { pub struct TimelineMarker { pub name: String, pub metadata: TracingMetadata, - pub time: u64, + pub time: time::PreciseTime, pub stack: Option>, } @@ -159,7 +159,7 @@ impl TimelineMarker { TimelineMarker { name: name, metadata: metadata, - time: time::precise_time_ns(), + time: time::PreciseTime::now(), stack: None, } }