diff --git a/src/swift/Time.swift b/src/swift/Time.swift index b6cd33cbf..538cd42fb 100644 --- a/src/swift/Time.swift +++ b/src/swift/Time.swift @@ -59,9 +59,13 @@ public struct DispatchTime : Comparable { public init(uptimeNanoseconds: UInt64) { var rawValue = uptimeNanoseconds #if HAVE_MACH - if (DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom) { - rawValue = (rawValue * UInt64(DispatchTime.timebaseInfo.denom) - + UInt64(DispatchTime.timebaseInfo.numer - 1)) / UInt64(DispatchTime.timebaseInfo.numer) + // UInt64.max means distantFuture. Do not try to scale it. + if rawValue != UInt64.max && DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom { + var (result, overflow) = rawValue.multipliedReportingOverflow(by: UInt64(DispatchTime.timebaseInfo.denom)) + if !overflow { + (result, overflow) = result.addingReportingOverflow(UInt64(DispatchTime.timebaseInfo.numer - 1)) + } + rawValue = overflow ? UInt64.max : result / UInt64(DispatchTime.timebaseInfo.numer) } #endif self.rawValue = dispatch_time_t(rawValue) @@ -70,8 +74,12 @@ public struct DispatchTime : Comparable { public var uptimeNanoseconds: UInt64 { var result = self.rawValue #if HAVE_MACH - if (DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom) { - result = result * UInt64(DispatchTime.timebaseInfo.numer) / UInt64(DispatchTime.timebaseInfo.denom) + var overflow: Bool + + // UInt64.max means distantFuture. Do not try to scale it. + if rawValue != UInt64.max && DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom { + (result, overflow) = result.multipliedReportingOverflow(by: UInt64(DispatchTime.timebaseInfo.numer)) + result = overflow ? UInt64.max : result / UInt64(DispatchTime.timebaseInfo.denom) } #endif return result