diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2018-06-23 13:52:52 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2018-07-07 10:52:31 +0200 |
| commit | c504d26c1cd4f4dbf9304415b12960c604f01ebf (patch) | |
| tree | 02a7ac72a8d81af75de2bbc83fe33101be4813a2 /src/librustc_codegen_utils | |
| parent | c5a6b51e442287d31b12591225d2e81a4345074d (diff) | |
| download | rust-c504d26c1cd4f4dbf9304415b12960c604f01ebf.tar.gz rust-c504d26c1cd4f4dbf9304415b12960c604f01ebf.zip | |
Move time_graph.rs to rustc/util
Diffstat (limited to 'src/librustc_codegen_utils')
| -rw-r--r-- | src/librustc_codegen_utils/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc_codegen_utils/time_graph.rs | 278 |
2 files changed, 0 insertions, 279 deletions
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 0298162bbb5..4ac0e3591b3 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -44,7 +44,6 @@ pub mod link; pub mod codegen_backend; pub mod symbol_names; pub mod symbol_names_test; -pub mod time_graph; pub mod llvm_target_features; /// check for the #[rustc_error] annotation, which forces an diff --git a/src/librustc_codegen_utils/time_graph.rs b/src/librustc_codegen_utils/time_graph.rs deleted file mode 100644 index a8502682a80..00000000000 --- a/src/librustc_codegen_utils/time_graph.rs +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::collections::HashMap; -use std::fs::File; -use std::io::prelude::*; -use std::marker::PhantomData; -use std::mem; -use std::sync::{Arc, Mutex}; -use std::time::Instant; - -const OUTPUT_WIDTH_IN_PX: u64 = 1000; -const TIME_LINE_HEIGHT_IN_PX: u64 = 20; -const TIME_LINE_HEIGHT_STRIDE_IN_PX: usize = 30; - -#[derive(Clone)] -struct Timing { - start: Instant, - end: Instant, - work_package_kind: WorkPackageKind, - name: String, - events: Vec<(String, Instant)>, -} - -#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)] -pub struct TimelineId(pub usize); - -#[derive(Clone)] -struct PerThread { - timings: Vec<Timing>, - open_work_package: Option<(Instant, WorkPackageKind, String)>, -} - -#[derive(Clone)] -pub struct TimeGraph { - data: Arc<Mutex<HashMap<TimelineId, PerThread>>>, -} - -#[derive(Clone, Copy)] -pub struct WorkPackageKind(pub &'static [&'static str]); - -pub struct Timeline { - token: Option<RaiiToken>, -} - -struct RaiiToken { - graph: TimeGraph, - timeline: TimelineId, - events: Vec<(String, Instant)>, - // The token must not be Send: - _marker: PhantomData<*const ()> -} - - -impl Drop for RaiiToken { - fn drop(&mut self) { - self.graph.end(self.timeline, mem::replace(&mut self.events, Vec::new())); - } -} - -impl TimeGraph { - pub fn new() -> TimeGraph { - TimeGraph { - data: Arc::new(Mutex::new(HashMap::new())) - } - } - - pub fn start(&self, - timeline: TimelineId, - work_package_kind: WorkPackageKind, - name: &str) -> Timeline { - { - let mut table = self.data.lock().unwrap(); - - let data = table.entry(timeline).or_insert(PerThread { - timings: Vec::new(), - open_work_package: None, - }); - - assert!(data.open_work_package.is_none()); - data.open_work_package = Some((Instant::now(), work_package_kind, name.to_string())); - } - - Timeline { - token: Some(RaiiToken { - graph: self.clone(), - timeline, - events: Vec::new(), - _marker: PhantomData, - }), - } - } - - fn end(&self, timeline: TimelineId, events: Vec<(String, Instant)>) { - let end = Instant::now(); - - let mut table = self.data.lock().unwrap(); - let data = table.get_mut(&timeline).unwrap(); - - if let Some((start, work_package_kind, name)) = data.open_work_package.take() { - data.timings.push(Timing { - start, - end, - work_package_kind, - name, - events, - }); - } else { - bug!("end timing without start?") - } - } - - pub fn dump(&self, output_filename: &str) { - let table = self.data.lock().unwrap(); - - for data in table.values() { - assert!(data.open_work_package.is_none()); - } - - let mut threads: Vec<PerThread> = - table.values().map(|data| data.clone()).collect(); - - threads.sort_by_key(|timeline| timeline.timings[0].start); - - let earliest_instant = threads[0].timings[0].start; - let latest_instant = threads.iter() - .map(|timeline| timeline.timings - .last() - .unwrap() - .end) - .max() - .unwrap(); - let max_distance = distance(earliest_instant, latest_instant); - - let mut file = File::create(format!("{}.html", output_filename)).unwrap(); - - writeln!(file, " - <html> - <head> - <style> - #threads a {{ - position: absolute; - overflow: hidden; - }} - #threads {{ - height: {total_height}px; - width: {width}px; - }} - - .timeline {{ - display: none; - width: {width}px; - position: relative; - }} - - .timeline:target {{ - display: block; - }} - - .event {{ - position: absolute; - }} - </style> - </head> - <body> - <div id='threads'> - ", - total_height = threads.len() * TIME_LINE_HEIGHT_STRIDE_IN_PX, - width = OUTPUT_WIDTH_IN_PX, - ).unwrap(); - - let mut color = 0; - for (line_index, thread) in threads.iter().enumerate() { - let line_top = line_index * TIME_LINE_HEIGHT_STRIDE_IN_PX; - - for span in &thread.timings { - let start = distance(earliest_instant, span.start); - let end = distance(earliest_instant, span.end); - - let start = normalize(start, max_distance, OUTPUT_WIDTH_IN_PX); - let end = normalize(end, max_distance, OUTPUT_WIDTH_IN_PX); - - let colors = span.work_package_kind.0; - - writeln!(file, "<a href='#timing{}' - style='top:{}px; \ - left:{}px; \ - width:{}px; \ - height:{}px; \ - background:{};'>{}</a>", - color, - line_top, - start, - end - start, - TIME_LINE_HEIGHT_IN_PX, - colors[color % colors.len()], - span.name, - ).unwrap(); - - color += 1; - } - } - - writeln!(file, " - </div> - ").unwrap(); - - let mut idx = 0; - for thread in threads.iter() { - for timing in &thread.timings { - let colors = timing.work_package_kind.0; - let height = TIME_LINE_HEIGHT_STRIDE_IN_PX * timing.events.len(); - writeln!(file, "<div class='timeline' - id='timing{}' - style='background:{};height:{}px;'>", - idx, - colors[idx % colors.len()], - height).unwrap(); - idx += 1; - let max = distance(timing.start, timing.end); - for (i, &(ref event, time)) in timing.events.iter().enumerate() { - let i = i as u64; - let time = distance(timing.start, time); - let at = normalize(time, max, OUTPUT_WIDTH_IN_PX); - writeln!(file, "<span class='event' - style='left:{}px;\ - top:{}px;'>{}</span>", - at, - TIME_LINE_HEIGHT_IN_PX * i, - event).unwrap(); - } - writeln!(file, "</div>").unwrap(); - } - } - - writeln!(file, " - </body> - </html> - ").unwrap(); - } -} - -impl Timeline { - pub fn noop() -> Timeline { - Timeline { token: None } - } - - /// Record an event which happened at this moment on this timeline. - /// - /// Events are displayed in the eventual HTML output where you can click on - /// a particular timeline and it'll expand to all of the events that - /// happened on that timeline. This can then be used to drill into a - /// particular timeline and see what events are happening and taking the - /// most time. - pub fn record(&mut self, name: &str) { - if let Some(ref mut token) = self.token { - token.events.push((name.to_string(), Instant::now())); - } - } -} - -fn distance(zero: Instant, x: Instant) -> u64 { - - let duration = x.duration_since(zero); - (duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64) // / div -} - -fn normalize(distance: u64, max: u64, max_pixels: u64) -> u64 { - (max_pixels * distance) / max -} - |
