Skip to content

Commit 8d63910

Browse files
committed
slurp up time calcualtions to inline forms
1 parent 9d0dcd3 commit 8d63910

File tree

1 file changed

+80
-21
lines changed

1 file changed

+80
-21
lines changed

stdlib/public/Concurrency/DispatchGlobalExecutor.inc

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,12 @@
2727
#if __has_include(<dispatch/private.h>)
2828
#include <dispatch/private.h>
2929
#else
30-
extern "C" {
3130
DISPATCH_ENUM(dispatch_clockid, uintptr_t,
3231
DISPATCH_CLOCKID_UPTIME = 1,
3332
DISPATCH_CLOCKID_MONOTONIC = 2,
3433
DISPATCH_CLOCKID_WALLTIME = 3,
3534
DISPATCH_CLOCKID_REALTIME = 3,
3635
);
37-
38-
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
39-
dispatch_time_t
40-
dispatch_time_from_nsec(dispatch_clockid_t clock, uint64_t deadline);
41-
}
4236
#endif
4337

4438
#if !defined(_WIN32)
@@ -242,19 +236,73 @@ static void swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
242236
}
243237

244238
#define DISPATCH_UP_OR_MONOTONIC_TIME_MASK (1ULL << 63)
239+
#define DISPATCH_WALLTIME_MASK (1ULL << 62)
240+
#define DISPATCH_TIME_MAX_VALUE (DISPATCH_WALLTIME_MASK - 1)
245241

246242
struct __swift_job_source {
247243
dispatch_source_t source;
248244
Job *job;
249245
};
250246

251-
static void __swift_run_job_leeway(Job *job) {
252-
dispatch_source_t source = (dispatch_source_t)job->Reserved;
253-
job->Reserved = nullptr;
247+
static void __swift_run_job_leeway(struct __swift_job_source *jobSource) {
248+
dispatch_source_t source = jobSource->source;
249+
Job *job = jobSource->job;
250+
free(jobSource);
254251
__swift_run_job(job);
255252
dispatch_release(source);
256253
}
257254

255+
#if defined(__i386__) || defined(__x86_64__) || !defined(__APPLE__)
256+
#define TIME_UNIT_USES_NANOSECONDS 1
257+
#else
258+
#define TIME_UNIT_USES_NANOSECONDS 0
259+
#endif
260+
261+
#if TIME_UNIT_USES_NANOSECONDS
262+
// x86 currently implements mach time in nanoseconds
263+
// this is NOT likely to change
264+
static inline uint64_t
265+
time_nano2mach(uint64_t nsec) {
266+
return nsec;
267+
}
268+
#else
269+
#define DISPATCH_USE_HOST_TIME 1
270+
#if defined(__APPLE__)
271+
#if defined(__arm__) || defined(__arm64__)
272+
// Apple arm platforms currently use a fixed mach timebase of 125/3 (24 MHz)
273+
static inline uint64_t
274+
time_nano2mach(uint64_t nsec) {
275+
if (!nsec) {
276+
return nsec;
277+
}
278+
if (nsec >= (uint64_t)INT64_MAX) {
279+
return INT64_MAX;
280+
}
281+
if (nsec >= UINT64_MAX / 3ull) {
282+
return (nsec / 125ull) * 3ull;
283+
} else {
284+
return (nsec * 3ull) / 125ull;
285+
}
286+
}
287+
#endif
288+
#endif
289+
#endif
290+
291+
static inline dispatch_time_t
292+
clock_and_value_to_time(int clock, long long deadline) {
293+
uint64_t value = time_nano2mach((uint64_t)deadline);
294+
if (value >= DISPATCH_TIME_MAX_VALUE) {
295+
return DISPATCH_TIME_FOREVER;
296+
}
297+
switch (clock) {
298+
case swift_clock_id_suspending:
299+
return value;
300+
case swift_clock_id_continuous:
301+
return value | DISPATCH_UP_OR_MONOTONIC_TIME_MASK;
302+
}
303+
__builtin_unreachable();
304+
}
305+
258306
SWIFT_CC(swift)
259307
static void swift_task_enqueueGlobalWithDeadlineImpl(long long sec,
260308
long long nsec,
@@ -276,20 +324,31 @@ static void swift_task_enqueueGlobalWithDeadlineImpl(long long sec,
276324
dispatchClock = DISPATCH_CLOCKID_UPTIME;
277325
}
278326
uint64_t deadline = sec * NSEC_PER_SEC + nsec;
279-
dispatch_time_t when = dispatch_time_from_nsec(dispatchClock, deadline);
280-
dispatch_source_t source =
281-
dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
282-
job->Reserved = source;
283-
dispatch_set_context(source, job);
284-
uint64_t leeway = 0;
327+
dispatch_time_t when = clock_and_value_to_time(clock, deadline);
328+
285329
if (tnsec != -1) {
286-
leeway = tsec * NSEC_PER_SEC + tnsec;
287-
}
288-
dispatch_source_set_timer(source, when,
289-
DISPATCH_TIME_FOREVER, leeway);
290-
dispatch_source_set_event_handler_f(source,
330+
uint64_t leeway = tsec * NSEC_PER_SEC + tnsec;
331+
332+
dispatch_source_t source =
333+
dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
334+
335+
struct __swift_job_source *jobSource =
336+
(struct __swift_job_source *)malloc(sizeof(struct __swift_job_source));
337+
jobSource->job = job;
338+
jobSource->source = source;
339+
340+
dispatch_set_context(source, jobSource);
341+
dispatch_source_set_timer(source, when,
342+
DISPATCH_TIME_FOREVER, leeway);
343+
dispatch_source_set_event_handler_f(source,
291344
(dispatch_function_t)&__swift_run_job_leeway);
292-
dispatch_activate(source);
345+
346+
dispatch_activate(source);
347+
} else {
348+
dispatch_function_t dispatchFunction = &__swift_run_job;
349+
void *dispatchContext = job;
350+
dispatch_after_f(when, queue, dispatchContext, dispatchFunction);
351+
}
293352
}
294353

295354
SWIFT_CC(swift)

0 commit comments

Comments
 (0)