Skip to content

Commit 94f4aca

Browse files
authored
Merge pull request #39480 from rjmccall/dispatchless-concurrency-builds
2 parents f872d00 + 1df455b commit 94f4aca

File tree

7 files changed

+70
-25
lines changed

7 files changed

+70
-25
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@
2525
#pragma clang diagnostic push
2626
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
2727

28+
// Does the runtime use a cooperative global executor?
29+
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
30+
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 1
31+
#else
32+
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 0
33+
#endif
34+
35+
// Does the runtime integrate with libdispatch?
36+
#ifndef SWIFT_CONCURRENCY_ENABLE_DISPATCH
37+
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
38+
#define SWIFT_CONCURRENCY_ENABLE_DISPATCH 0
39+
#else
40+
#define SWIFT_CONCURRENCY_ENABLE_DISPATCH 1
41+
#endif
42+
#endif
43+
2844
namespace swift {
2945
class DefaultActor;
3046
class TaskOptionRecord;
@@ -661,10 +677,14 @@ void swift_task_enqueueGlobalWithDelay(unsigned long long delay, Job *job);
661677
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
662678
void swift_task_enqueueMainExecutor(Job *job);
663679

680+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
681+
664682
/// Enqueue the given job on the main executor.
665683
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
666684
void swift_task_enqueueOnDispatchQueue(Job *job, HeapObject *queue);
667685

686+
#endif
687+
668688
/// A hook to take over global enqueuing.
669689
typedef SWIFT_CC(swift) void (*swift_task_enqueueGlobal_original)(Job *job);
670690
SWIFT_EXPORT_FROM(swift_Concurrency)
@@ -806,6 +826,17 @@ void swift_task_reportUnexpectedExecutor(
806826
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
807827
JobPriority swift_task_getCurrentThreadPriority(void);
808828

829+
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
830+
831+
/// Donate this thread to the global executor until either the
832+
/// given condition returns true or we've run out of cooperative
833+
/// tasks to run.
834+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
835+
void swift_task_donateThreadToGlobalExecutorUntil(bool (*condition)(void*),
836+
void *context);
837+
838+
#endif
839+
809840
#ifdef __APPLE__
810841
/// A magic symbol whose address is the mask to apply to a frame pointer to
811842
/// signal that it is an async frame. Do not try to read the actual value of

stdlib/public/Concurrency/Actor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
#include "TaskPrivate.h"
4747
#include "VoucherSupport.h"
4848

49-
#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
49+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
5050
#include <dispatch/dispatch.h>
5151
#endif
5252

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ endif()
3535
set(SWIFT_RUNTIME_CONCURRENCY_C_FLAGS)
3636
set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS)
3737

38+
if(NOT SWIFT_CONCURRENCY_USES_DISPATCH)
39+
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
40+
"-DSWIFT_CONCURRENCY_ENABLE_DISPATCH=0")
41+
endif()
42+
3843
if(NOT swift_concurrency_async_fp_mode)
3944
set(swift_concurrency_async_fp_mode "always")
4045
endif()

stdlib/public/Concurrency/GlobalExecutor.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
#include "TaskPrivate.h"
6060
#include "Error.h"
6161

62-
#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
62+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
6363
#include <dispatch/dispatch.h>
6464

6565
#if !defined(_WIN32)
@@ -178,15 +178,21 @@ static Job *claimNextFromJobQueue() {
178178
}
179179
}
180180

181-
void swift::donateThreadToGlobalExecutorUntil(bool (*condition)(void *),
182-
void *conditionContext) {
181+
void swift::
182+
swift_task_donateThreadToGlobalExecutorUntil(bool (*condition)(void *),
183+
void *conditionContext) {
183184
while (!condition(conditionContext)) {
184185
auto job = claimNextFromJobQueue();
185186
if (!job) return;
186187
swift_job_run(job, ExecutorRef::generic());
187188
}
188189
}
189190

191+
#elif !SWIFT_CONCURRENCY_ENABLE_DISPATCH
192+
193+
// No implementation. The expectation is that integrators in this
194+
// configuration will hook all the appropriate functions.
195+
190196
#else
191197

192198
// Ensure that Job's layout is compatible with what Dispatch expects.
@@ -330,6 +336,9 @@ static void swift_task_enqueueGlobalImpl(Job *job) {
330336

331337
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
332338
insertIntoJobQueue(job);
339+
#elif !SWIFT_CONCURRENCY_ENABLE_DISPATCH
340+
swift_reportError(0, "operation unsupported without libdispatch: "
341+
"swift_task_enqueueGlobal");
333342
#else
334343
// We really want four things from the global execution service:
335344
// - Enqueuing work should have minimal runtime and memory overhead.
@@ -385,6 +394,9 @@ static void swift_task_enqueueGlobalWithDelayImpl(unsigned long long delay,
385394

386395
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
387396
insertIntoDelayedJobQueue(delay, job);
397+
#elif !SWIFT_CONCURRENCY_ENABLE_DISPATCH
398+
swift_reportError(0, "operation unsupported without libdispatch: "
399+
"swift_task_enqueueGlobalWithDelay");
388400
#else
389401

390402
dispatch_function_t dispatchFunction = &__swift_run_job;
@@ -419,6 +431,9 @@ static void swift_task_enqueueMainExecutorImpl(Job *job) {
419431

420432
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
421433
insertIntoJobQueue(job);
434+
#elif !SWIFT_CONCURRENCY_ENABLE_DISPATCH
435+
swift_reportError(0, "operation unsupported without libdispatch: "
436+
"swift_task_enqueueMainExecutor");
422437
#else
423438

424439
JobPriority priority = job->getPriority();
@@ -439,7 +454,7 @@ void swift::swift_task_enqueueMainExecutor(Job *job) {
439454
swift_task_enqueueMainExecutorImpl(job);
440455
}
441456

442-
#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
457+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
443458
void swift::swift_task_enqueueOnDispatchQueue(Job *job,
444459
HeapObject *_queue) {
445460
JobPriority priority = job->getPriority();
@@ -449,7 +464,8 @@ void swift::swift_task_enqueueOnDispatchQueue(Job *job,
449464
#endif
450465

451466
ExecutorRef swift::swift_task_getMainExecutor() {
452-
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
467+
#if !SWIFT_CONCURRENCY_ENABLE_DISPATCH
468+
// FIXME: this isn't right for the non-cooperative environment
453469
return ExecutorRef::generic();
454470
#else
455471
return ExecutorRef::forOrdinary(
@@ -459,7 +475,8 @@ ExecutorRef swift::swift_task_getMainExecutor() {
459475
}
460476

461477
bool ExecutorRef::isMainExecutor() const {
462-
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
478+
#if !SWIFT_CONCURRENCY_ENABLE_DISPATCH
479+
// FIXME: this isn't right for the non-cooperative environment
463480
return isGeneric();
464481
#else
465482
return Identity == reinterpret_cast<HeapObject*>(&_dispatch_main_q);

stdlib/public/Concurrency/Task.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "Debug.h"
2828
#include "Error.h"
2929

30-
#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
30+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3131
#include <dispatch/dispatch.h>
3232
#endif
3333

@@ -248,7 +248,7 @@ static void destroyTask(SWIFT_CONTEXT HeapObject *obj) {
248248
}
249249

250250
static ExecutorRef executorForEnqueuedJob(Job *job) {
251-
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
251+
#if !SWIFT_CONCURRENCY_ENABLE_DISPATCH
252252
return ExecutorRef::generic();
253253
#else
254254
void *jobQueue = job->SchedulerPrivate[Job::DispatchQueueIndex];
@@ -1065,13 +1065,19 @@ void swift::swift_continuation_logFailedCheck(const char *message) {
10651065
swift_reportError(0, message);
10661066
}
10671067

1068+
SWIFT_RUNTIME_ATTRIBUTE_NORETURN
10681069
SWIFT_CC(swift)
10691070
static void swift_task_asyncMainDrainQueueImpl() {
10701071
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
10711072
bool Finished = false;
1072-
donateThreadToGlobalExecutorUntil([](void *context) {
1073+
swift_task_donateThreadToGlobalExecutorUntil([](void *context) {
10731074
return *reinterpret_cast<bool*>(context);
10741075
}, &Finished);
1076+
#elif !SWIFT_CONCURRENCY_ENABLE_DISPATCH
1077+
// FIXME: consider implementing a concurrent global main queue for
1078+
// these environments?
1079+
swift_reportError(0, "operation unsupported without libdispatch: "
1080+
"swift_task_asyncMainDrainQueue");
10751081
#else
10761082
#if defined(_WIN32)
10771083
static void(FAR *pfndispatch_main)(void) = NULL;

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include "queue" // TODO: remove and replace with usage of our mpsc queue
3535
#include <atomic>
3636
#include <assert.h>
37-
#if !SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
37+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3838
#include <dispatch/dispatch.h>
3939
#endif
4040

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,20 +100,6 @@ void asyncLet_addImpl(AsyncTask *task, AsyncLet *asyncLet,
100100
/// Clear the active task reference for the current thread.
101101
AsyncTask *_swift_task_clearCurrent();
102102

103-
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
104-
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 1
105-
#else
106-
#define SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR 0
107-
#endif
108-
109-
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
110-
/// Donate this thread to the global executor until either the
111-
/// given condition returns true or we've run out of cooperative
112-
/// tasks to run.
113-
void donateThreadToGlobalExecutorUntil(bool (*condition)(void*),
114-
void *context);
115-
#endif
116-
117103
/// release() establishes a happens-before relation with a preceding acquire()
118104
/// on the same address.
119105
void _swift_tsan_acquire(void *addr);

0 commit comments

Comments
 (0)