Skip to content

Commit f8b423d

Browse files
Use platform shims for clock_gettime to support wasi-libc
This change adds platform shims for `clock_gettime` so that we can use it in Swift code even when the clock id macros can't be imported through ClangImporter like wasi-libc's definitions. Also wasi-libc's `timespec.tv_sec` and `timespec.tv_nsec` are not imported as `Int` in Swift, so we need to cast them to `UInt64` before doing arithmetic operations on them.
1 parent 5463e8e commit f8b423d

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

Sources/FoundationEssentials/Date.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import Glibc
2020
import WinSDK
2121
#endif
2222

23+
internal import _FoundationCShims
24+
2325
#if !FOUNDATION_FRAMEWORK
2426
@available(macOS 10.10, iOS 8.0, watchOS 2.0, tvOS 9.0, *)
2527
public typealias TimeInterval = Double
@@ -232,7 +234,7 @@ extension Date {
232234
return TimeInterval(Double(li.QuadPart) / 10_000_000.0 - Self.timeIntervalBetween1601AndReferenceDate)
233235
#else
234236
var ts: timespec = timespec()
235-
clock_gettime(CLOCK_REALTIME, &ts)
237+
_platform_shims_clock_realtime_gettime(&ts)
236238
var ret = TimeInterval(ts.tv_sec) - Self.timeIntervalBetween1970AndReferenceDate
237239
ret += (1.0E-9 * TimeInterval(ts.tv_nsec))
238240
return ret

Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ final class _ProcessInfo: Sendable {
128128
let time: UInt64 = ullTime
129129
#else
130130
var ts: timespec = timespec()
131-
clock_gettime(CLOCK_MONOTONIC_RAW, &ts)
132-
let time: UInt64 = UInt64(ts.tv_sec * 1000000000 + ts.tv_nsec)
131+
_platform_shims_clock_monotonic_raw_gettime(&ts)
132+
let time: UInt64 = UInt64(ts.tv_sec) * 1000000000 + UInt64(ts.tv_nsec)
133133
#endif
134134
let timeString = String(time, radix: 16, uppercase: true)
135135
let padding = String(repeating: "0", count: 16 - timeString.count)
@@ -562,7 +562,7 @@ extension _ProcessInfo {
562562
return TimeInterval(GetTickCount64()) / 1000.0
563563
#else
564564
var ts = timespec()
565-
guard clock_gettime(CLOCK_MONOTONIC, &ts) == 0 else {
565+
guard _platform_shims_clock_monotonic_gettime(&ts) == 0 else {
566566
return 0
567567
}
568568
return TimeInterval(ts.tv_sec) +

Sources/_FoundationCShims/include/platform_shims.h

+10
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,14 @@ typedef enum {
6868
INTERNAL const char * _Nonnull _platform_shims_kOSThermalNotificationPressureLevelName();
6969
#endif
7070

71+
// Define clock_gettime shims for each clock type so that we can use them in Swift
72+
// even if clock id macros can't be imported through ClangImporter.
73+
74+
#if !defined(_WIN32)
75+
#include <time.h>
76+
int _platform_shims_clock_monotonic_raw_gettime(struct timespec * _Nonnull ts);
77+
int _platform_shims_clock_monotonic_gettime(struct timespec * _Nonnull ts);
78+
int _platform_shims_clock_realtime_gettime(struct timespec * _Nonnull ts);
79+
#endif
80+
7181
#endif /* CSHIMS_PLATFORM_SHIMS */

Sources/_FoundationCShims/platform_shims.c

+17
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,20 @@ mach_port_t _platform_mach_task_self() {
6767
}
6868
#endif
6969

70+
#if !defined(_WIN32)
71+
int _platform_shims_clock_monotonic_raw_gettime(struct timespec * _Nonnull ts) {
72+
#if __wasi__ // WASI does not support CLOCK_MONOTONIC_RAW. Fall back to CLOCK_MONOTONIC.
73+
return clock_gettime(CLOCK_MONOTONIC, ts);
74+
#else
75+
return clock_gettime(CLOCK_MONOTONIC_RAW, ts);
76+
#endif
77+
}
78+
79+
int _platform_shims_clock_monotonic_gettime(struct timespec * _Nonnull ts) {
80+
return clock_gettime(CLOCK_MONOTONIC, ts);
81+
}
82+
83+
int _platform_shims_clock_realtime_gettime(struct timespec * _Nonnull ts) {
84+
return clock_gettime(CLOCK_REALTIME, ts);
85+
}
86+
#endif

0 commit comments

Comments
 (0)