@@ -6,7 +6,7 @@ use std::time::{Duration, Instant as StdInstant};
66/// This number is pretty random, but it has been shown to approximately cause
77/// some sample programs to run within an order of magnitude of real time on desktop CPUs.
88/// (See `tests/pass/shims/time-with-isolation*.rs`.)
9- const NANOSECONDS_PER_BASIC_BLOCK : u64 = 5000 ;
9+ const NANOSECONDS_PER_BASIC_BLOCK : u128 = 5000 ;
1010
1111#[ derive( Debug ) ]
1212pub struct Instant {
@@ -16,7 +16,7 @@ pub struct Instant {
1616#[ derive( Debug ) ]
1717enum InstantKind {
1818 Host ( StdInstant ) ,
19- Virtual { nanoseconds : u64 } ,
19+ Virtual { nanoseconds : u128 } ,
2020}
2121
2222impl Instant {
@@ -25,9 +25,8 @@ impl Instant {
2525 InstantKind :: Host ( instant) =>
2626 instant. checked_add ( duration) . map ( |i| Instant { kind : InstantKind :: Host ( i) } ) ,
2727 InstantKind :: Virtual { nanoseconds } =>
28- u128 :: from ( nanoseconds)
28+ nanoseconds
2929 . checked_add ( duration. as_nanos ( ) )
30- . and_then ( |n| u64:: try_from ( n) . ok ( ) )
3130 . map ( |nanoseconds| Instant { kind : InstantKind :: Virtual { nanoseconds } } ) ,
3231 }
3332 }
@@ -39,7 +38,17 @@ impl Instant {
3938 (
4039 InstantKind :: Virtual { nanoseconds } ,
4140 InstantKind :: Virtual { nanoseconds : earlier } ,
42- ) => Duration :: from_nanos ( nanoseconds. saturating_sub ( earlier) ) ,
41+ ) => {
42+ let duration = nanoseconds. saturating_sub ( earlier) ;
43+ // `Duration` does not provide a nice constructor from a `u128` of nanoseconds,
44+ // so we have to implement this ourselves.
45+ // It is possible for second to overflow because u64::MAX < (u128::MAX / 1e9).
46+ // It will be saturated to u64::MAX seconds if the value after division exceeds u64::MAX.
47+ let seconds = u64:: try_from ( duration / 1_000_000_000 ) . unwrap_or ( u64:: MAX ) ;
48+ // It is impossible for nanosecond to overflow because u32::MAX > 1e9.
49+ let nanosecond = u32:: try_from ( duration. wrapping_rem ( 1_000_000_000 ) ) . unwrap ( ) ;
50+ Duration :: new ( seconds, nanosecond)
51+ }
4352 _ => panic ! ( "all `Instant` must be of the same kind" ) ,
4453 }
4554 }
@@ -59,7 +68,7 @@ enum ClockKind {
5968 } ,
6069 Virtual {
6170 /// The "current virtual time".
62- nanoseconds : Cell < u64 > ,
71+ nanoseconds : Cell < u128 > ,
6372 } ,
6473}
6574
@@ -93,8 +102,11 @@ impl Clock {
93102 ClockKind :: Host { .. } => std:: thread:: sleep ( duration) ,
94103 ClockKind :: Virtual { nanoseconds } => {
95104 // Just pretend that we have slept for some time.
96- let nanos: u64 = duration. as_nanos ( ) . try_into ( ) . unwrap ( ) ;
97- nanoseconds. update ( |x| x + nanos) ;
105+ let nanos: u128 = duration. as_nanos ( ) ;
106+ nanoseconds. update ( |x| {
107+ x. checked_add ( nanos)
108+ . expect ( "Miri's virtual clock cannot represent an execution this long" )
109+ } ) ;
98110 }
99111 }
100112 }
0 commit comments