1+ /// Stats for a nested span in the execution segment that is tracked by the [`CycleTracker`].
2+ #[ derive( Clone , Debug , Default ) ]
3+ pub struct SpanInfo {
4+ /// The name of the span.
5+ pub tag : String ,
6+ /// The cycle count at which the span starts.
7+ pub start : usize ,
8+ }
9+
110#[ derive( Clone , Debug , Default ) ]
211pub struct CycleTracker {
312 /// Stack of span names, with most recent at the end
4- stack : Vec < String > ,
13+ stack : Vec < SpanInfo > ,
14+ /// Depth of the stack.
15+ depth : usize ,
516}
617
718impl CycleTracker {
@@ -10,29 +21,41 @@ impl CycleTracker {
1021 }
1122
1223 pub fn top ( & self ) -> Option < & String > {
13- self . stack . last ( )
24+ match self . stack . last ( ) {
25+ Some ( span) => Some ( & span. tag ) ,
26+ _ => None
27+ }
1428 }
1529
1630 /// Starts a new cycle tracker span for the given name.
17- /// If a span already exists for the given name, it ends the existing span and pushes a new one
18- /// to the vec.
19- pub fn start ( & mut self , mut name : String ) {
31+ /// If a span already exists for the given name, it ends the existing span and pushes a new one to the vec.
32+ pub fn start ( & mut self , mut name : String , cycles_count : usize ) {
2033 // hack to remove "CT-" prefix
2134 if name. starts_with ( "CT-" ) {
2235 name = name. split_off ( 3 ) ;
2336 }
24- self . stack . push ( name) ;
37+ self . stack . push ( SpanInfo {
38+ tag : name. clone ( ) ,
39+ start : cycles_count,
40+ } ) ;
41+ let padding = "│ " . repeat ( self . depth ) ;
42+ tracing:: info!( "{}┌╴{}" , padding, name) ;
43+ self . depth += 1 ;
2544 }
2645
2746 /// Ends the cycle tracker span for the given name.
2847 /// If no span exists for the given name, it panics.
29- pub fn end ( & mut self , mut name : String ) {
48+ pub fn end ( & mut self , mut name : String , cycles_count : usize ) {
3049 // hack to remove "CT-" prefix
3150 if name. starts_with ( "CT-" ) {
3251 name = name. split_off ( 3 ) ;
3352 }
34- let stack_top = self . stack . pop ( ) ;
35- assert_eq ! ( stack_top. unwrap( ) , name, "Stack top does not match name" ) ;
53+ let SpanInfo { tag, start } = self . stack . pop ( ) . unwrap ( ) ;
54+ assert_eq ! ( tag, name, "Stack top does not match name" ) ;
55+ self . depth -= 1 ;
56+ let padding = "│ " . repeat ( self . depth ) ;
57+ let span_cycles = cycles_count - start;
58+ tracing:: info!( "{}└╴{} cycles" , padding, span_cycles) ;
3659 }
3760
3861 /// Ends the current cycle tracker span.
@@ -42,7 +65,11 @@ impl CycleTracker {
4265
4366 /// Get full name of span with all parent names separated by ";" in flamegraph format
4467 pub fn get_full_name ( & self ) -> String {
45- self . stack . join ( ";" )
68+ self . stack
69+ . iter ( )
70+ . map ( |span_info| span_info. tag . clone ( ) )
71+ . collect :: < Vec < String > > ( )
72+ . join ( ";" )
4673 }
4774}
4875
0 commit comments