diff --git a/src/cargo/util/profile.rs b/src/cargo/util/profile.rs index 7d32adc3f60..ce49eee26cc 100644 --- a/src/cargo/util/profile.rs +++ b/src/cargo/util/profile.rs @@ -4,6 +4,7 @@ use std::mem; use std::time; use std::iter::repeat; use std::cell::RefCell; +use std::io::{stdout, StdoutLock, Write}; thread_local!(static PROFILE_STACK: RefCell> = RefCell::new(Vec::new())); thread_local!(static MESSAGES: RefCell> = RefCell::new(Vec::new())); @@ -39,14 +40,24 @@ impl Drop for Profiler { None => return, }; - let start = PROFILE_STACK.with(|stack| stack.borrow_mut().pop().unwrap()); + let (start, stack_len) = PROFILE_STACK.with(|stack| { + let mut stack = stack.borrow_mut(); + let start = stack.pop().unwrap(); + (start, stack.len()) + }); let duration = start.elapsed(); let duration_ms = duration.as_secs() * 1000 + u64::from(duration.subsec_nanos() / 1_000_000); - let stack_len = PROFILE_STACK.with(|stack| stack.borrow().len()); + let msg = ( + stack_len, + duration_ms, + mem::replace(&mut self.desc, String::new()), + ); + MESSAGES.with(|msgs| msgs.borrow_mut().push(msg)); + if stack_len == 0 { - fn print(lvl: usize, msgs: &[Message], enabled: usize) { + fn print(lvl: usize, msgs: &[Message], enabled: usize, stdout: &mut StdoutLock) { if lvl > enabled { return; } @@ -55,26 +66,23 @@ impl Drop for Profiler { if l != lvl { continue; } - println!( + writeln!( + stdout, "{} {:6}ms - {}", repeat(" ").take(lvl + 1).collect::(), time, msg - ); + ).expect("printing profiling info to stdout"); - print(lvl + 1, &msgs[last..i], enabled); + print(lvl + 1, &msgs[last..i], enabled, stdout); last = i; } } - MESSAGES.with(|msgs_rc| { - let mut msgs = msgs_rc.borrow_mut(); - msgs.push((0, duration_ms, mem::replace(&mut self.desc, String::new()))); - print(0, &msgs, enabled); - }); - } else { + let stdout = stdout(); MESSAGES.with(|msgs| { - let msg = mem::replace(&mut self.desc, String::new()); - msgs.borrow_mut().push((stack_len, duration_ms, msg)); + let mut msgs = msgs.borrow_mut(); + print(0, &msgs, enabled, &mut stdout.lock()); + msgs.clear(); }); } }