Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hassila committed Nov 15, 2022
1 parent daef960 commit 0e3230a
Show file tree
Hide file tree
Showing 6 changed files with 309 additions and 0 deletions.
25 changes: 25 additions & 0 deletions Benchmarks/Clocks/Clocks.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import DateTime

import BenchmarkSupport
@main extension BenchmarkRunner {}

@_dynamicReplacement(for: registerBenchmarks)
func benchmarks() {

Benchmark.defaultDesiredDuration = .seconds(2)
Benchmark.defaultDesiredIterations = 1_000
Benchmark.defaultThroughputScalingFactor = .kilo

Benchmark("InternalUTCClock.now") { benchmark in
for _ in 0 ..< benchmark.throughputScalingFactor.rawValue {
BenchmarkSupport.blackHole(InternalUTCClock.now)
}
}

Benchmark("Foundation.Date") { benchmark in
for _ in 0 ..< benchmark.throughputScalingFactor.rawValue {
BenchmarkSupport.blackHole(Foundation.Date())
}
}

}
68 changes: 68 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"pins" : [
{
"identity" : "package-benchmark",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ordo-one/package-benchmark",
"state" : {
"revision" : "13d1a5fc228f5553acb22cdbb7f7c217e4b8c51e",
"version" : "0.4.3"
}
},
{
"identity" : "package-jemalloc",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ordo-one/package-jemalloc",
"state" : {
"revision" : "e8a5db026963f5bfeac842d9d3f2cc8cde323b49",
"version" : "1.0.0"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser",
"state" : {
"revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d",
"version" : "1.2.0"
}
},
{
"identity" : "swift-extras-json",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-extras/swift-extras-json",
"state" : {
"revision" : "122b9454ef01bf89a4c190b8fd3717ddd0a2fbd0",
"version" : "0.6.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system",
"state" : {
"revision" : "025bcb1165deab2e20d4eaba79967ce73013f496",
"version" : "1.2.1"
}
},
{
"identity" : "texttable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ordo-one/TextTable",
"state" : {
"revision" : "a27a07300cf4ae322e0079ca0a475c5583dd575f",
"version" : "0.0.2"
}
}
],
"version" : 2
}
39 changes: 39 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// swift-tools-version: 5.7

import PackageDescription

let package = Package(
name: "package-datetime",
platforms: [
.macOS(.v13)
],
products: [
.library(
name: "DateTime",
targets: ["DateTime"]
)
],
dependencies: [
.package(url: "https://github.com/ordo-one/package-benchmark", .upToNextMajor(from: "0.4.2"))
],
targets: [
.target(
name: "DateTime",
dependencies: []
),
.testTarget(
name: "DateTimeTests",
dependencies: ["DateTime"]
),

// Benchmark targets
.executableTarget(
name: "Clocks",
dependencies: [
.product(name: "BenchmarkSupport", package: "package-benchmark"),
"DateTime"
],
path: "Benchmarks/Clocks"
)
]
)
5 changes: 5 additions & 0 deletions Sources/DateTime/FoundationExports.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file contains the specific Foundation constructs we allow to use internally

@_exported import struct Foundation.Calendar
@_exported import struct Foundation.Date
@_exported import struct Foundation.TimeZone
152 changes: 152 additions & 0 deletions Sources/DateTime/InternalUTCClock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// An implementation of an UTC clock using Ordo:s internal datetime representation

// swiftlint:disable line_length identifier_name

// Largely adopted by Swift's ContinuousClock
// https://github.com/apple/swift/blob/48987de3d3ab228eed4867949795c188759df234/stdlib/public/Concurrency/ContinuousClock.swift#L49

#if canImport(Darwin)
import Darwin
#elseif canImport(Glibc)
import Glibc
#else
#error("Unsupported Platform")
#endif

public struct InternalUTCClock {
/// A continuous point in time used for `InternalUTCClock`.
public struct Instant: Codable, Sendable {
internal var _value: Swift.Duration

internal init(_value: Swift.Duration) {
self._value = _value
}
}

public init() {}
}

public extension Clock where Self == InternalUTCClock {
/// A clock that measures time that always increments but does not stop
/// incrementing while the system is asleep.
///
/// try await Task.sleep(until: .now + .seconds(3), clock: .continuous)
///
static var internalUTC: InternalUTCClock { return InternalUTCClock() }
}

extension InternalUTCClock: Clock {
/// The current continuous instant.
public var now: InternalUTCClock.Instant {
InternalUTCClock.now
}

/// The minimum non-zero resolution between any two calls to `now`.
public var minimumResolution: Swift.Duration {
var resolution = timespec()

let result = clock_getres(CLOCK_REALTIME, &resolution)

guard result == 0 else {
fatalError("Failed to get realtime clock resolution in clock_getres(), errno = \(errno)")
}

let seconds = Int64(resolution.tv_sec)
let attoseconds = Int64(resolution.tv_nsec) * 1_000_000_000

return Duration(secondsComponent: seconds, attosecondsComponent: attoseconds)
}

/// The current continuous instant.
public static var now: InternalUTCClock.Instant {
var currentTime = timespec()
let result = clock_gettime(CLOCK_REALTIME, &currentTime)

guard result == 0 else {
fatalError("Failed to get current time in clock_gettime(), errno = \(errno)")
}

let seconds = Int64(currentTime.tv_sec)
let attoseconds = Int64(currentTime.tv_nsec) * 1_000_000_000

return InternalUTCClock.Instant(_value: Duration(secondsComponent: seconds, attosecondsComponent: attoseconds))
}

/// Suspend task execution until a given deadline within a tolerance.
/// If no tolerance is specified then the system may adjust the deadline
/// to coalesce CPU wake-ups to more efficiently process the wake-ups in
/// a more power efficient manner.
///
/// If the task is canceled before the time ends, this function throws
/// `CancellationError`.
///
/// This function doesn't block the underlying thread.
public func sleep(
until deadline: Instant, tolerance: Swift.Duration? = nil
) async throws {
try await Task.sleep(until: deadline, tolerance: tolerance, clock: .internalUTC)
}
}

extension InternalUTCClock.Instant: InstantProtocol {
public static var now: InternalUTCClock.Instant { InternalUTCClock.now }

public func advanced(by duration: Swift.Duration) -> InternalUTCClock.Instant {
return InternalUTCClock.Instant(_value: _value + duration)
}

public func duration(to other: InternalUTCClock.Instant) -> Swift.Duration {
other._value - _value
}

public func hash(into hasher: inout Hasher) {
hasher.combine(_value)
}

public static func == (
_ lhs: InternalUTCClock.Instant, _ rhs: InternalUTCClock.Instant
) -> Bool {
return lhs._value == rhs._value
}

public static func < (
_ lhs: InternalUTCClock.Instant, _ rhs: InternalUTCClock.Instant
) -> Bool {
return lhs._value < rhs._value
}

@inlinable
public static func + (
_ lhs: InternalUTCClock.Instant, _ rhs: Swift.Duration
) -> InternalUTCClock.Instant {
lhs.advanced(by: rhs)
}

@inlinable
public static func += (
_ lhs: inout InternalUTCClock.Instant, _ rhs: Swift.Duration
) {
lhs = lhs.advanced(by: rhs)
}

@inlinable
public static func - (
_ lhs: InternalUTCClock.Instant, _ rhs: Swift.Duration
) -> InternalUTCClock.Instant {
lhs.advanced(by: .zero - rhs)
}

@inlinable
public static func -= (
_ lhs: inout InternalUTCClock.Instant, _ rhs: Swift.Duration
) {
lhs = lhs.advanced(by: .zero - rhs)
}

@inlinable
public static func - (
_ lhs: InternalUTCClock.Instant, _ rhs: InternalUTCClock.Instant
) -> Swift.Duration {
rhs.duration(to: lhs)
}
}
20 changes: 20 additions & 0 deletions Tests/DateTimeTests/DateTime.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@testable import DateTime
import XCTest

final class DateTimeTests: XCTestCase {
func testExample() throws {
let time = InternalUTCClock().measure {
print("Time now: \(InternalUTCClock.now)")
print("Time now: \(InternalUTCClock.now._value.components)")
print("Resolution: \(InternalUTCClock().minimumResolution)")
}
print("Elapsed time in nanoseconds \(time.components.attoseconds / 1_000_000_000)")
let time2 = InternalUTCClock().measure {
_ = 47
}
print("Elapsed time in nanoseconds for empty closure \(time2.components.attoseconds / 1_000_000_000)")
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
}
}

0 comments on commit 0e3230a

Please sign in to comment.