@@ -35,6 +35,7 @@ use crate::telemetry::{Encodable, ThreadLocalEncoder};
3535use pin_project_lite:: pin_project;
3636use smallvec:: SmallVec ;
3737use std:: future:: Future ;
38+ use std:: num:: NonZeroU64 ;
3839use std:: pin:: Pin ;
3940use std:: sync:: Arc ;
4041use std:: sync:: atomic:: Ordering ;
@@ -54,7 +55,7 @@ pin_project! {
5455 frames: FrameBuf ,
5556 // Monotonic nanoseconds when the frames in `frames` were captured.
5657 // Only meaningful when `frames.has_data()`.
57- pending_capture_ts: u64 ,
58+ pending_capture_ts: Option < NonZeroU64 > ,
5859 // Snapshot of SharedState::task_dump_idle_threshold_ns at construction;
5960 // promotes the atomic load off the poll hot path.
6061 idle_threshold_ns: u64 ,
@@ -69,7 +70,7 @@ impl<F> TaskDumped<F> {
6970 shared,
7071 task_id,
7172 frames : FrameBuf :: new ( ) ,
72- pending_capture_ts : 0 ,
73+ pending_capture_ts : None ,
7374 idle_threshold_ns,
7475 }
7576 }
@@ -91,38 +92,42 @@ impl<F: Future> Future for TaskDumped<F> {
9192 // after capture resumes.
9293 if this. frames . has_data ( ) {
9394 this. frames . clear ( ) ;
94- * this. pending_capture_ts = 0 ;
95+ * this. pending_capture_ts = None ;
9596 }
9697 return this. inner . poll ( cx) ;
9798 }
9899
99100 // If we have captured frames from a previous idle, decide whether
100101 // that idle was long enough to emit.
101- let should_emit = if this. frames . has_data ( ) {
102- let now = crate :: telemetry:: events:: clock_monotonic_ns ( ) ;
103- now. saturating_sub ( * this. pending_capture_ts ) > * this. idle_threshold_ns
104- } else {
105- false
102+ let poll_start = crate :: telemetry:: recorder:: poll_start_ts_or_now ( ) ;
103+ let should_emit = match * this. pending_capture_ts {
104+ Some ( ts) if this. frames . has_data ( ) => {
105+ poll_start. saturating_sub ( ts. get ( ) ) > * this. idle_threshold_ns
106+ }
107+ _ => false ,
106108 } ;
107109
108110 let result = this. inner . as_mut ( ) . poll ( cx) ;
109111
110112 if should_emit {
111- this. frames
112- . emit ( this. shared , * this. task_id , * this. pending_capture_ts ) ;
113+ this. frames . emit (
114+ this. shared ,
115+ * this. task_id ,
116+ this. pending_capture_ts . unwrap ( ) . get ( ) ,
117+ ) ;
113118 }
114119
115120 match & result {
116121 Poll :: Ready ( _) => {
117122 // Terminal. Nothing more to capture; discard stale frames.
118123 this. frames . clear ( ) ;
119- * this. pending_capture_ts = 0 ;
124+ * this. pending_capture_ts = None ;
120125 }
121126 Poll :: Pending => {
122127 // Capture the yield point we just landed on, for the next
123128 // poll's threshold check.
124129 this. frames . capture ( this. inner . as_mut ( ) ) ;
125- * this. pending_capture_ts = crate :: telemetry :: events :: clock_monotonic_ns ( ) ;
130+ * this. pending_capture_ts = NonZeroU64 :: new ( poll_start ) ;
126131 }
127132 }
128133
0 commit comments