1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Swift
/// A mechanism in which to measure time, and delay work until a given point
/// in time.
///
/// Types that conform to the `Clock` protocol define a concept of "now" which
/// is the specific instant in time that property is accessed. Any pair of calls
/// to the `now` property may have a minimum duration between them - this
/// minimum resolution is exposed by the `minimumResolution` property to inform
/// any user of the type the expected granularity of accuracy.
///
/// One of the primary uses for clocks is to schedule task sleeping. This method
/// resumes the calling task after a given deadline has been met or passed with
/// a given tolerance value. The tolerance is expected as a leeway around the
/// deadline. The clock may reschedule tasks within the tolerance to ensure
/// efficient execution of resumptions by reducing potential operating system
/// wake-ups. If no tolerance is specified (i.e. nil is passed in) the sleep
/// function is expected to schedule with a default tolerance strategy.
///
/// For more information about specific clocks see `ContinuousClock` and
/// `SuspendingClock`.
@available(SwiftStdlib 5.7, *)
public protocol Clock<Duration>: Sendable {
associatedtype Duration
associatedtype Instant: InstantProtocol where Instant.Duration == Duration
var now: Instant { get }
var minimumResolution: Instant.Duration { get }
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
func sleep(until deadline: Instant, tolerance: Instant.Duration?) async throws
#endif
}
@available(SwiftStdlib 5.7, *)
extension Clock {
/// Measure the elapsed time to execute a closure.
///
/// let clock = ContinuousClock()
/// let elapsed = clock.measure {
/// someWork()
/// }
@available(SwiftStdlib 5.7, *)
public func measure(_ work: () throws -> Void) rethrows -> Instant.Duration {
let start = now
try work()
let end = now
return start.duration(to: end)
}
/// Measure the elapsed time to execute an asynchronous closure.
///
/// let clock = ContinuousClock()
/// let elapsed = await clock.measure {
/// await someWork()
/// }
@available(SwiftStdlib 5.7, *)
@_alwaysEmitIntoClient
@_allowFeatureSuppression(OptionalIsolatedParameters)
public func measure(
isolation: isolated (any Actor)? = #isolation,
_ work: () async throws -> Void
) async rethrows -> Instant.Duration {
try await measure(work)
}
@available(SwiftStdlib 5.7, *)
@_unsafeInheritExecutor // for ABI compatibility
@usableFromInline
internal func measure(
_ work: () async throws -> Void
) async rethrows -> Instant.Duration {
let start = now
try await work()
let end = now
return start.duration(to: end)
}
}
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
@available(SwiftStdlib 5.7, *)
extension Clock {
/// Suspends for the given duration.
///
/// Prefer to use the `sleep(until:tolerance:)` method on `Clock` if you have
/// access to an absolute instant.
@available(SwiftStdlib 5.7, *)
@_alwaysEmitIntoClient
public func sleep(
for duration: Instant.Duration,
tolerance: Instant.Duration? = nil
) async throws {
try await sleep(until: now.advanced(by: duration), tolerance: tolerance)
}
}
#endif
enum _ClockID: Int32 {
case continuous = 1
case suspending = 2
}
@available(SwiftStdlib 5.7, *)
@_silgen_name("swift_get_time")
internal func _getTime(
seconds: UnsafeMutablePointer<Int64>,
nanoseconds: UnsafeMutablePointer<Int64>,
clock: CInt)
@available(SwiftStdlib 5.7, *)
@_silgen_name("swift_get_clock_res")
internal func _getClockRes(
seconds: UnsafeMutablePointer<Int64>,
nanoseconds: UnsafeMutablePointer<Int64>,
clock: CInt)
|