From 5eb8ce461ff596a0ba35e7ec7498056ef2e5b216 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 29 Aug 2021 18:07:28 +0000 Subject: [PATCH] [Concurrency] repair cooperative global executor This patch guards some includes of libdispatch headers so that platforms that doesn't support libdispatch can build cooperative executor runtime. And fixed missing implementations for cooperative mode. --- stdlib/public/Concurrency/Executor.swift | 2 ++ stdlib/public/Concurrency/GlobalExecutor.cpp | 19 ++++++++++++++++++- stdlib/public/Concurrency/Task.cpp | 6 ++++++ stdlib/public/Concurrency/TaskGroup.cpp | 2 ++ stdlib/public/Concurrency/TaskPrivate.h | 2 ++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/stdlib/public/Concurrency/Executor.swift b/stdlib/public/Concurrency/Executor.swift index d4456fd6d7fa3..1daf120fee8fa 100644 --- a/stdlib/public/Concurrency/Executor.swift +++ b/stdlib/public/Concurrency/Executor.swift @@ -93,6 +93,7 @@ func _checkExpectedExecutor(_filenameStart: Builtin.RawPointer, _filenameStart, _filenameLength, _filenameIsASCII, _line, _executor) } +#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME // This must take a DispatchQueueShim, not something like AnyObject, // or else SILGen will emit a retain/release in unoptimized builds, // which won't work because DispatchQueues aren't actually @@ -119,3 +120,4 @@ internal final class DispatchQueueShim: UnsafeSendable, SerialExecutor { return UnownedSerialExecutor(ordinary: self) } } +#endif \ No newline at end of file diff --git a/stdlib/public/Concurrency/GlobalExecutor.cpp b/stdlib/public/Concurrency/GlobalExecutor.cpp index 5fbdec4ac9f23..1e9214321b903 100644 --- a/stdlib/public/Concurrency/GlobalExecutor.cpp +++ b/stdlib/public/Concurrency/GlobalExecutor.cpp @@ -59,12 +59,15 @@ #include "TaskPrivate.h" #include "Error.h" +#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR #include #if !defined(_WIN32) #include #endif +#endif + using namespace swift; SWIFT_CC(swift) @@ -180,7 +183,7 @@ void swift::donateThreadToGlobalExecutorUntil(bool (*condition)(void *), while (!condition(conditionContext)) { auto job = claimNextFromJobQueue(); if (!job) return; - job->run(ExecutorRef::generic()); + swift_job_run(job, ExecutorRef::generic()); } } @@ -405,21 +408,35 @@ void swift::swift_task_enqueueMainExecutor(Job *job) { swift_task_enqueueMainExecutorImpl(job); } +#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR void swift::swift_task_enqueueOnDispatchQueue(Job *job, HeapObject *_queue) { JobPriority priority = job->getPriority(); auto queue = reinterpret_cast(_queue); dispatchEnqueue(queue, job, (dispatch_qos_class_t)priority, queue); } +#endif + +#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR +static HeapObject _swift_mainExecutorIdentity; +#endif ExecutorRef swift::swift_task_getMainExecutor() { +#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR + return ExecutorRef::forOrdinary(&_swift_mainExecutorIdentity, nullptr); +#else return ExecutorRef::forOrdinary( reinterpret_cast(&_dispatch_main_q), _swift_task_getDispatchQueueSerialExecutorWitnessTable()); +#endif } bool ExecutorRef::isMainExecutor() const { +#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR + return Identity == &_swift_mainExecutorIdentity; +#else return Identity == reinterpret_cast(&_dispatch_main_q); +#endif } #define OVERRIDE_GLOBAL_EXECUTOR COMPATIBILITY_OVERRIDE diff --git a/stdlib/public/Concurrency/Task.cpp b/stdlib/public/Concurrency/Task.cpp index 860c0a831ccac..bc30b81103612 100644 --- a/stdlib/public/Concurrency/Task.cpp +++ b/stdlib/public/Concurrency/Task.cpp @@ -27,7 +27,9 @@ #include "Debug.h" #include "Error.h" +#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR #include +#endif #if !defined(_WIN32) #include @@ -242,12 +244,16 @@ static void destroyTask(SWIFT_CONTEXT HeapObject *obj) { } static ExecutorRef executorForEnqueuedJob(Job *job) { +#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR + return ExecutorRef::generic(); +#else void *jobQueue = job->SchedulerPrivate[Job::DispatchQueueIndex]; if (jobQueue == DISPATCH_QUEUE_GLOBAL_EXECUTOR) return ExecutorRef::generic(); else return ExecutorRef::forOrdinary(reinterpret_cast(jobQueue), _swift_task_getDispatchQueueSerialExecutorWitnessTable()); +#endif } static void jobInvoke(void *obj, void *unused, uint32_t flags) { diff --git a/stdlib/public/Concurrency/TaskGroup.cpp b/stdlib/public/Concurrency/TaskGroup.cpp index 56dd88d91f9ef..e2ce5c0951ad2 100644 --- a/stdlib/public/Concurrency/TaskGroup.cpp +++ b/stdlib/public/Concurrency/TaskGroup.cpp @@ -34,7 +34,9 @@ #include "queue" // TODO: remove and replace with usage of our mpsc queue #include #include +#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR #include +#endif #if !defined(_WIN32) #include diff --git a/stdlib/public/Concurrency/TaskPrivate.h b/stdlib/public/Concurrency/TaskPrivate.h index 0984ac4b6a418..a605819e92133 100644 --- a/stdlib/public/Concurrency/TaskPrivate.h +++ b/stdlib/public/Concurrency/TaskPrivate.h @@ -112,12 +112,14 @@ void _swift_tsan_release(void *addr); /// executors. #define DISPATCH_QUEUE_GLOBAL_EXECUTOR (void *)1 +#if !defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME) inline SerialExecutorWitnessTable * _swift_task_getDispatchQueueSerialExecutorWitnessTable() { extern SerialExecutorWitnessTable wtable SWIFT_ASM_LABEL_WITH_PREFIX("$ss17DispatchQueueShimCScfsWP"); return &wtable; } +#endif // ==== ------------------------------------------------------------------------