@@ -28,8 +28,22 @@ impl PerformanceCounterTimestamp {
2828 }
2929
3030 pub fn duration_since ( & self , other : Self ) -> Duration {
31- let freq = perf_freq ( ) ;
32- Duration :: from_secs_f64 ( ( self . 0 - other. 0 ) as f64 / freq as f64 )
31+ let freq = perf_freq ( ) as i128 ;
32+ debug_assert ! ( freq > 0 ) ;
33+
34+ let diff = self . 0 as i128 - other. 0 as i128 ;
35+
36+ if diff <= 0 {
37+ Duration :: ZERO
38+ } else {
39+ let diff = diff as u128 ;
40+ let freq = freq as u128 ;
41+
42+ let secs = diff / freq;
43+ let nanos = ( ( diff % freq) * 1_000_000_000u128 ) / freq;
44+
45+ Duration :: new ( secs as u64 , nanos as u32 )
46+ }
3347 }
3448
3549 pub fn now ( ) -> Self {
@@ -62,3 +76,26 @@ impl Sub<Duration> for PerformanceCounterTimestamp {
6276 Self ( self . 0 - ( rhs. as_secs_f64 ( ) * freq as f64 ) as i64 )
6377 }
6478}
79+
80+ #[ cfg( test) ]
81+ mod tests {
82+ use super :: * ;
83+
84+ #[ test]
85+ fn duration_since_returns_zero_when_earlier ( ) {
86+ let freq = perf_freq ( ) ;
87+ let base = PerformanceCounterTimestamp :: new ( 10 * freq) ;
88+ let earlier = PerformanceCounterTimestamp :: new ( 9 * freq) ;
89+
90+ assert_eq ! ( earlier. duration_since( base) , Duration :: ZERO ) ;
91+ }
92+
93+ #[ test]
94+ fn duration_since_handles_positive_diff ( ) {
95+ let freq = perf_freq ( ) ;
96+ let base = PerformanceCounterTimestamp :: new ( 10 * freq) ;
97+ let later = PerformanceCounterTimestamp :: new ( 11 * freq) ;
98+
99+ assert_eq ! ( later. duration_since( base) , Duration :: from_secs( 1 ) ) ;
100+ }
101+ }
0 commit comments