@@ -59,9 +59,13 @@ public struct DispatchTime : Comparable {
59
59
public init ( uptimeNanoseconds: UInt64 ) {
60
60
var rawValue = uptimeNanoseconds
61
61
#if HAVE_MACH
62
- if ( DispatchTime . timebaseInfo. numer != DispatchTime . timebaseInfo. denom) {
63
- rawValue = ( rawValue * UInt64( DispatchTime . timebaseInfo. denom)
64
- + UInt64( DispatchTime . timebaseInfo. numer - 1 ) ) / UInt64( DispatchTime . timebaseInfo. numer)
62
+ // UInt64.max means distantFuture. Do not try to scale it.
63
+ if rawValue != UInt64 . max && DispatchTime . timebaseInfo. numer != DispatchTime . timebaseInfo. denom {
64
+ var ( result, overflow) = rawValue. multipliedReportingOverflow ( by: UInt64 ( DispatchTime . timebaseInfo. denom) )
65
+ if !overflow {
66
+ ( result, overflow) = result. addingReportingOverflow ( UInt64 ( DispatchTime . timebaseInfo. numer - 1 ) )
67
+ }
68
+ rawValue = overflow ? UInt64 . max : result / UInt64( DispatchTime . timebaseInfo. numer)
65
69
}
66
70
#endif
67
71
self . rawValue = dispatch_time_t ( rawValue)
@@ -70,8 +74,12 @@ public struct DispatchTime : Comparable {
70
74
public var uptimeNanoseconds : UInt64 {
71
75
var result = self . rawValue
72
76
#if HAVE_MACH
73
- if ( DispatchTime . timebaseInfo. numer != DispatchTime . timebaseInfo. denom) {
74
- result = result * UInt64( DispatchTime . timebaseInfo. numer) / UInt64( DispatchTime . timebaseInfo. denom)
77
+ var overflow : Bool
78
+
79
+ // UInt64.max means distantFuture. Do not try to scale it.
80
+ if rawValue != UInt64 . max && DispatchTime . timebaseInfo. numer != DispatchTime . timebaseInfo. denom {
81
+ ( result, overflow) = result. multipliedReportingOverflow ( by: UInt64 ( DispatchTime . timebaseInfo. numer) )
82
+ result = overflow ? UInt64 . max : result / UInt64( DispatchTime . timebaseInfo. denom)
75
83
}
76
84
#endif
77
85
return result
0 commit comments