Last active
March 25, 2024 17:41
-
-
Save YOCKOW/12d9607cb30f40b79fb2 to your computer and use it in GitHub Desktop.
Get `timespec` in Swift. It is no longer necessary to implement clock_gettime() even on OS X.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| TimeSpec.swift | |
| © 2016 YOCKOW. | |
| */ | |
| // <Usage> | |
| // let now:TimeSpec? = Clock.Calendar.timespec | |
| // if now != nil { | |
| // /* ... */ | |
| // } | |
| #if os(Linux) | |
| import Glibc | |
| public typealias TimeSpec = timespec | |
| #elseif os(OSX) || os(iOS) || os(watchOS) || (tvOS) | |
| import Darwin | |
| private let mach_task_self:()->mach_port_t = { return mach_task_self_ } | |
| public typealias TimeSpec = mach_timespec_t | |
| #endif | |
| extension Double { | |
| public init(_ ts: TimeSpec) { | |
| self = Double(ts.tv_nsec) * 1.0E-9 + Double(ts.tv_sec) | |
| } | |
| } | |
| extension TimeSpec { | |
| public var double:Double { | |
| return Double(self) | |
| } | |
| } | |
| public func + (left:TimeSpec, right:TimeSpec) -> TimeSpec { | |
| var result = left | |
| result.tv_sec += right.tv_sec | |
| result.tv_nsec += right.tv_nsec | |
| if (result.tv_nsec >= 1_000_000_000) { | |
| result.tv_sec += 1 | |
| result.tv_nsec -= 1_000_000_000 | |
| } | |
| return result | |
| } | |
| public func - (left:TimeSpec, right:TimeSpec) -> TimeSpec { | |
| var result = left | |
| result.tv_sec -= right.tv_sec | |
| result.tv_nsec -= right.tv_nsec | |
| if (result.tv_nsec < 0) { | |
| result.tv_sec -= 1 | |
| result.tv_nsec += 1_000_000_000 | |
| } | |
| return result | |
| } | |
| public enum Clock { | |
| case Calendar | |
| case System | |
| public var timespec:TimeSpec? { | |
| var result:TimeSpec = TimeSpec(tv_sec:0, tv_nsec:0) | |
| let clock_id:Int32 | |
| var return_value:Int32 = -1 | |
| #if os(Linux) | |
| clock_id = (self == .Calendar) ? CLOCK_REALTIME : CLOCK_MONOTONIC | |
| return_value = clock_gettime(clock_id, &result) | |
| #elseif os(OSX) || os(iOS) || os(watchOS) || (tvOS) | |
| clock_id = (self == .Calendar) ? CALENDAR_CLOCK : SYSTEM_CLOCK | |
| var clock_name: clock_serv_t = 0 | |
| return_value = host_get_clock_service(mach_host_self(), clock_id, &clock_name) | |
| if return_value != 0 { return nil } | |
| return_value = clock_get_time(clock_name, &result) | |
| _ = mach_port_deallocate(mach_task_self(), clock_name) | |
| #endif | |
| return (return_value == 0) ? result : nil | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
very well said!