@@ -59,9 +59,13 @@ public struct DispatchTime : Comparable {
5959 public init ( uptimeNanoseconds: UInt64 ) {
6060 var rawValue = uptimeNanoseconds
6161#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)
6569 }
6670#endif
6771 self . rawValue = dispatch_time_t ( rawValue)
@@ -70,8 +74,12 @@ public struct DispatchTime : Comparable {
7074 public var uptimeNanoseconds : UInt64 {
7175 var result = self . rawValue
7276#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)
7583 }
7684#endif
7785 return result
0 commit comments