Skip to content

Commit d98950c

Browse files
committed
feat: Implement DispatchTime using Swift Concurrency.
1 parent 5108dec commit d98950c

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
@available(macOS 13, *)
14+
public typealias DispatchTime = ContinuousClock.Instant
15+
16+
/// The very first time someone tries to reference a `uptimeNanoseconds` or a similar
17+
/// function that references a beginning point, this variable will be initialized as a beginning
18+
/// reference point. This guarantees that all calls to `uptimeNanoseconds` or similar
19+
/// will be 0 or greater.
20+
///
21+
/// By design, it is not possible to related `ContinuousClock.Instant` to
22+
/// `ProcessInfo.processInfo.systemUptime`, and even if one devised such
23+
/// a mechanism, it would open the door for fingerprinting. It's best to let the concept
24+
/// of uptime be relative to previous uptime calls.
25+
@available(macOS 13, *)
26+
private let uptimeBeginning: DispatchTime = DispatchTime.now()
27+
28+
@available(macOS 13, *)
29+
extension DispatchTime {
30+
public static func now() -> DispatchTime {
31+
now
32+
}
33+
34+
public var uptimeNanoseconds: UInt64 {
35+
let beginning = uptimeBeginning
36+
let rightNow = DispatchTime.now()
37+
let uptimeDuration: Int64 = beginning.duration(to: rightNow).nanosecondsClamped
38+
guard uptimeDuration >= 0 else {
39+
assertionFailure("It shouldn't be possible to get a negative duration since uptimeBeginning.")
40+
return 0
41+
}
42+
return UInt64(uptimeDuration)
43+
}
44+
}
45+
46+
// NOTE: The following was copied from swift-nio/Source/NIOCore/TimeAmount+Duration on June 27, 2025
47+
// It was copied rather than brought via dependencies to avoid introducing
48+
// a dependency on swift-nio for such a small piece of code.
49+
//
50+
// This library will need to have no depedendencies to be able to be integrated into GCD.
51+
@available(macOS 13, iOS 16, tvOS 16, watchOS 9, *)
52+
extension Swift.Duration {
53+
/// The duration represented as nanoseconds, clamped to maximum expressible value.
54+
fileprivate var nanosecondsClamped: Int64 {
55+
let components = self.components
56+
57+
let secondsComponentNanos = components.seconds.multipliedReportingOverflow(by: 1_000_000_000)
58+
let attosCompononentNanos = components.attoseconds / 1_000_000_000
59+
let combinedNanos = secondsComponentNanos.partialValue.addingReportingOverflow(attosCompononentNanos)
60+
61+
guard
62+
!secondsComponentNanos.overflow,
63+
!combinedNanos.overflow
64+
else {
65+
return .max
66+
}
67+
68+
return combinedNanos.partialValue
69+
}
70+
}

0 commit comments

Comments
 (0)