1 //===----------------------------------------------------------------------===//
3 // This source file is part of the Swift.org open source project
5 // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6 // Licensed under Apache License v2.0 with Runtime Library Exception
8 // See http://swift.org/LICENSE.txt for license information
9 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11 //===----------------------------------------------------------------------===//
14 // DISPATCH_TIME_NOW: ok
15 // DISPATCH_TIME_FOREVER: ok
19 public struct DispatchTime : Comparable {
21 private static let timebaseInfo: mach_timebase_info_data_t = {
22 var info = mach_timebase_info_data_t(numer: 1, denom: 1)
23 mach_timebase_info(&info)
28 public let rawValue: dispatch_time_t
30 public static func now() -> DispatchTime {
31 let t = CDispatch.dispatch_time(0, 0)
32 return DispatchTime(rawValue: t)
35 public static let distantFuture = DispatchTime(rawValue: ~0)
37 fileprivate init(rawValue: dispatch_time_t) {
38 self.rawValue = rawValue
41 /// Creates a `DispatchTime` relative to the system clock that
45 /// - uptimeNanoseconds: The number of nanoseconds since boot, excluding
46 /// time the system spent asleep
47 /// - Returns: A new `DispatchTime`
48 /// - Discussion: This clock is the same as the value returned by
49 /// `mach_absolute_time` when converted into nanoseconds.
50 /// On some platforms, the nanosecond value is rounded up to a
51 /// multiple of the Mach timebase, using the conversion factors
52 /// returned by `mach_timebase_info()`. The nanosecond equivalent
53 /// of the rounded result can be obtained by reading the
54 /// `uptimeNanoseconds` property.
55 /// Note that `DispatchTime(uptimeNanoseconds: 0)` is
56 /// equivalent to `DispatchTime.now()`, that is, its value
57 /// represents the number of nanoseconds since boot (excluding
58 /// system sleep time), not zero nanoseconds since boot.
59 public init(uptimeNanoseconds: UInt64) {
60 var rawValue = uptimeNanoseconds
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)
67 self.rawValue = dispatch_time_t(rawValue)
70 public var uptimeNanoseconds: UInt64 {
71 var result = self.rawValue
73 if (DispatchTime.timebaseInfo.numer != DispatchTime.timebaseInfo.denom) {
74 result = result * UInt64(DispatchTime.timebaseInfo.numer) / UInt64(DispatchTime.timebaseInfo.denom)
81 public func <(a: DispatchTime, b: DispatchTime) -> Bool {
82 if a.rawValue == ~0 || b.rawValue == ~0 { return false }
83 return a.rawValue < b.rawValue
86 public func ==(a: DispatchTime, b: DispatchTime) -> Bool {
87 return a.rawValue == b.rawValue
90 public struct DispatchWallTime : Comparable {
91 public let rawValue: dispatch_time_t
93 public static func now() -> DispatchWallTime {
94 return DispatchWallTime(rawValue: CDispatch.dispatch_walltime(nil, 0))
97 public static let distantFuture = DispatchWallTime(rawValue: ~0)
99 fileprivate init(rawValue: dispatch_time_t) {
100 self.rawValue = rawValue
103 public init(timespec: timespec) {
105 self.rawValue = CDispatch.dispatch_walltime(&t, 0)
109 public func <(a: DispatchWallTime, b: DispatchWallTime) -> Bool {
110 if b.rawValue == ~0 {
111 return a.rawValue != ~0
112 } else if a.rawValue == ~0 {
115 return -Int64(bitPattern: a.rawValue) < -Int64(bitPattern: b.rawValue)
118 public func ==(a: DispatchWallTime, b: DispatchWallTime) -> Bool {
119 return a.rawValue == b.rawValue
122 public enum DispatchTimeInterval {
124 case milliseconds(Int)
125 case microseconds(Int)
126 case nanoseconds(Int)
127 @_downgrade_exhaustivity_check
130 internal var rawValue: Int64 {
132 case .seconds(let s): return Int64(s) * Int64(NSEC_PER_SEC)
133 case .milliseconds(let ms): return Int64(ms) * Int64(NSEC_PER_MSEC)
134 case .microseconds(let us): return Int64(us) * Int64(NSEC_PER_USEC)
135 case .nanoseconds(let ns): return Int64(ns)
136 case .never: return Int64.max
140 public static func ==(lhs: DispatchTimeInterval, rhs: DispatchTimeInterval) -> Bool {
142 case (.never, .never): return true
143 case (.never, _): return false
144 case (_, .never): return false
145 default: return lhs.rawValue == rhs.rawValue
150 public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime {
151 let t = CDispatch.dispatch_time(time.rawValue, interval.rawValue)
152 return DispatchTime(rawValue: t)
155 public func -(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime {
156 let t = CDispatch.dispatch_time(time.rawValue, -interval.rawValue)
157 return DispatchTime(rawValue: t)
160 public func +(time: DispatchTime, seconds: Double) -> DispatchTime {
161 let interval = seconds * Double(NSEC_PER_SEC)
162 let t = CDispatch.dispatch_time(time.rawValue,
163 interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
164 return DispatchTime(rawValue: t)
167 public func -(time: DispatchTime, seconds: Double) -> DispatchTime {
168 let interval = -seconds * Double(NSEC_PER_SEC)
169 let t = CDispatch.dispatch_time(time.rawValue,
170 interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
171 return DispatchTime(rawValue: t)
174 public func +(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime {
175 let t = CDispatch.dispatch_time(time.rawValue, interval.rawValue)
176 return DispatchWallTime(rawValue: t)
179 public func -(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime {
180 let t = CDispatch.dispatch_time(time.rawValue, -interval.rawValue)
181 return DispatchWallTime(rawValue: t)
184 public func +(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
185 let interval = seconds * Double(NSEC_PER_SEC)
186 let t = CDispatch.dispatch_time(time.rawValue,
187 interval.isInfinite || interval.isNaN ? Int64.max : Int64(interval))
188 return DispatchWallTime(rawValue: t)
191 public func -(time: DispatchWallTime, seconds: Double) -> DispatchWallTime {
192 let interval = -seconds * Double(NSEC_PER_SEC)
193 let t = CDispatch.dispatch_time(time.rawValue,
194 interval.isInfinite || interval.isNaN ? Int64.min : Int64(interval))
195 return DispatchWallTime(rawValue: t)