@@ -6,7 +6,7 @@ use std::time::{Duration, Instant as StdInstant};
6
6
/// This number is pretty random, but it has been shown to approximately cause
7
7
/// some sample programs to run within an order of magnitude of real time on desktop CPUs.
8
8
/// (See `tests/pass/shims/time-with-isolation*.rs`.)
9
- const NANOSECONDS_PER_BASIC_BLOCK : u64 = 5000 ;
9
+ const NANOSECONDS_PER_BASIC_BLOCK : u128 = 5000 ;
10
10
11
11
#[ derive( Debug ) ]
12
12
pub struct Instant {
@@ -16,7 +16,7 @@ pub struct Instant {
16
16
#[ derive( Debug ) ]
17
17
enum InstantKind {
18
18
Host ( StdInstant ) ,
19
- Virtual { nanoseconds : u64 } ,
19
+ Virtual { nanoseconds : u128 } ,
20
20
}
21
21
22
22
impl Instant {
@@ -25,9 +25,8 @@ impl Instant {
25
25
InstantKind :: Host ( instant) =>
26
26
instant. checked_add ( duration) . map ( |i| Instant { kind : InstantKind :: Host ( i) } ) ,
27
27
InstantKind :: Virtual { nanoseconds } =>
28
- u128 :: from ( nanoseconds)
28
+ nanoseconds
29
29
. checked_add ( duration. as_nanos ( ) )
30
- . and_then ( |n| u64:: try_from ( n) . ok ( ) )
31
30
. map ( |nanoseconds| Instant { kind : InstantKind :: Virtual { nanoseconds } } ) ,
32
31
}
33
32
}
@@ -39,7 +38,17 @@ impl Instant {
39
38
(
40
39
InstantKind :: Virtual { nanoseconds } ,
41
40
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
+ }
43
52
_ => panic ! ( "all `Instant` must be of the same kind" ) ,
44
53
}
45
54
}
@@ -59,7 +68,7 @@ enum ClockKind {
59
68
} ,
60
69
Virtual {
61
70
/// The "current virtual time".
62
- nanoseconds : Cell < u64 > ,
71
+ nanoseconds : Cell < u128 > ,
63
72
} ,
64
73
}
65
74
@@ -93,8 +102,11 @@ impl Clock {
93
102
ClockKind :: Host { .. } => std:: thread:: sleep ( duration) ,
94
103
ClockKind :: Virtual { nanoseconds } => {
95
104
// 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
+ } ) ;
98
110
}
99
111
}
100
112
}
0 commit comments