Skip to content

Commit ce4abce

Browse files
committed
attempt to move the dispatch specific code to .inc files
1 parent 144581c commit ce4abce

File tree

8 files changed

+104
-14
lines changed

8 files changed

+104
-14
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,11 @@ void swift_task_enqueue(Job *job, SerialExecutorRef executor);
715715
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
716716
void swift_task_enqueueGlobal(Job *job);
717717

718+
/// Invoke an executor's `checkIsolated` or otherwise equivalent API,
719+
/// that will crash if the current executor is NOT the passed executor.
720+
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
721+
void swift_task_checkIsolated(SerialExecutorRef executor);
722+
718723
/// A count in nanoseconds.
719724
using JobDelay = unsigned long long;
720725

@@ -781,6 +786,12 @@ SWIFT_CC(swift) void (*swift_task_enqueueGlobalWithDeadline_hook)(
781786
int clock, Job *job,
782787
swift_task_enqueueGlobalWithDeadline_original original);
783788

789+
typedef SWIFT_CC(swift) void (*swift_task_checkIsolated_original)(SerialExecutorRef executor);
790+
SWIFT_EXPORT_FROM(swift_Concurrency)
791+
SWIFT_CC(swift) void (*swift_task_checkIsolated_hook)(
792+
SerialExecutorRef executor, swift_task_checkIsolated_original original);
793+
794+
784795
typedef SWIFT_CC(swift) bool (*swift_task_isOnExecutor_original)(
785796
HeapObject *executor,
786797
const Metadata *selfType,

stdlib/public/Concurrency/Actor.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919
#include <atomic>
2020
#include <new>
2121

22+
//#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
23+
//#include <dispatch/dispatch.h>
24+
//#endif // SWIFT_CONCURRENCY_ENABLE_DISPATCH
25+
2226
#include "../CompatibilityOverride/CompatibilityOverride.h"
2327
#include "swift/ABI/Actor.h"
2428
#include "swift/ABI/Task.h"
29+
#include "TaskPrivate.h"
2530
#include "swift/Basic/ListMerger.h"
2631
#include "swift/Concurrency/Actor.h"
2732
#include "swift/Runtime/AccessibleFunction.h"
@@ -313,12 +318,6 @@ bool _task_serialExecutor_isSameExclusiveExecutionContext(
313318
const Metadata *selfType,
314319
const SerialExecutorWitnessTable *wtable);
315320

316-
extern "C" SWIFT_CC(swift)
317-
bool _task_serialExecutor_checkIsolated(
318-
HeapObject *executor,
319-
const Metadata *selfType,
320-
const SerialExecutorWitnessTable *wtable);
321-
322321
SWIFT_CC(swift)
323322
static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef executor) {
324323
auto current = ExecutorTrackingInfo::current();
@@ -352,10 +351,9 @@ static bool swift_task_isCurrentExecutorImpl(SerialExecutorRef executor) {
352351
executor.getSerialExecutorWitnessTable());
353352
}
354353

355-
_task_serialExecutor_checkIsolated(
356-
executor.getIdentity(),
357-
swift_getObjectType(executor.getIdentity()),
358-
executor.getSerialExecutorWitnessTable());
354+
// FIXME: we cannot do this direcly here as we have to still provide the boolean API
355+
// TODO: introduce new entry point that just checks this, that the precondition APIs can use
356+
swift_task_checkIsolated(executor);
359357

360358
return true;
361359
}

stdlib/public/Concurrency/CooperativeGlobalExecutor.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ static void insertDelayedJob(Job *newJob, JobDeadline deadline) {
136136
*position = newJob;
137137
}
138138

139+
SWIFT_CC(swift)
140+
static void swift_task_checkIsolatedImpl(SerialExecutorRef executor) {
141+
_task_serialExecutor_checkIsolated(
142+
executor.getIdentity(), swift_getObjectType(executor.getIdentity()),
143+
executor.getSerialExecutorWitnessTable());
144+
}
145+
139146
/// Insert a job into the cooperative global queue with a delay.
140147
SWIFT_CC(swift)
141148
static void swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,

stdlib/public/Concurrency/DispatchGlobalExecutor.inc

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/// swift_task_enqueueGlobalImpl
1919
/// swift_task_enqueueGlobalWithDelayImpl
2020
/// swift_task_enqueueMainExecutorImpl
21+
/// swift_task_checkIsolated
2122
/// as well as any Dispatch-specific functions for the runtime.
2223
///
2324
///===------------------------------------------------------------------===///
@@ -233,7 +234,7 @@ static void swift_task_enqueueGlobalImpl(Job *job) {
233234

234235
SWIFT_CC(swift)
235236
static void swift_task_enqueueGlobalWithDelayImpl(JobDelay delay,
236-
Job *job) {
237+
Job *job) {
237238
assert(job && "no job provided");
238239

239240
dispatch_function_t dispatchFunction = &__swift_run_job;
@@ -383,3 +384,35 @@ void swift::swift_task_enqueueOnDispatchQueue(Job *job,
383384
auto queue = reinterpret_cast<dispatch_queue_t>(_queue);
384385
dispatchEnqueue(queue, job, (dispatch_qos_class_t)priority, queue);
385386
}
387+
388+
/// Recognize if the SerialExecutor is specifically a `DispatchSerialQueue`
389+
/// by comparing witness tables and return it if true.
390+
static dispatch_queue_s *getAsDispatchSerialQueue(SerialExecutorRef executor) {
391+
auto executorWitnessTable = reinterpret_cast<const WitnessTable *>(
392+
executor.getSerialExecutorWitnessTable());
393+
auto serialQueueWitnessTable = reinterpret_cast<const WitnessTable *>(
394+
_swift_task_getDispatchQueueSerialExecutorWitnessTable());
395+
396+
if (swift_compareWitnessTables(executorWitnessTable,
397+
serialQueueWitnessTable)) {
398+
return reinterpret_cast<dispatch_queue_s *>(executor.getIdentity());
399+
} else {
400+
return nullptr;
401+
}
402+
}
403+
404+
/// If the executor is a `DispatchSerialQueue` we're able to invoke the
405+
/// dispatch's precondition API directly -- this is more efficient than going
406+
/// through the runtime call to end up calling the same API, and also allows us
407+
/// to perform this assertion on earlier platforms, where the `checkIsolated`
408+
/// requirement/witness was not shipping yet.
409+
SWIFT_CC(swift)
410+
static void swift_task_checkIsolatedImpl(SerialExecutorRef executor) {
411+
if (auto queue = getAsDispatchSerialQueue(executor)) {
412+
dispatch_assert_queue(queue);
413+
} else {
414+
_task_serialExecutor_checkIsolated(
415+
executor.getIdentity(), swift_getObjectType(executor.getIdentity()),
416+
executor.getSerialExecutorWitnessTable());
417+
}
418+
}

stdlib/public/Concurrency/GlobalExecutor.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,19 @@ SWIFT_CC(swift)
9090
void (*swift::swift_task_enqueueMainExecutor_hook)(
9191
Job *job, swift_task_enqueueMainExecutor_original original) = nullptr;
9292

93+
SWIFT_CC(swift)
94+
void (*swift::swift_task_checkIsolated_hook)(
95+
SerialExecutorRef executor,
96+
swift_task_checkIsolated_original original) = nullptr;
97+
98+
// FIXME: add hook for checkIsolated?
99+
100+
extern "C" SWIFT_CC(swift)
101+
bool _task_serialExecutor_checkIsolated(
102+
HeapObject *executor,
103+
const Metadata *selfType,
104+
const SerialExecutorWitnessTable *wtable);
105+
93106
#if SWIFT_CONCURRENCY_COOPERATIVE_GLOBAL_EXECUTOR
94107
#include "CooperativeGlobalExecutor.inc"
95108
#elif SWIFT_CONCURRENCY_ENABLE_DISPATCH
@@ -132,6 +145,13 @@ void swift::swift_task_enqueueGlobalWithDeadline(
132145
swift_task_enqueueGlobalWithDeadlineImpl(sec, nsec, tsec, tnsec, clock, job);
133146
}
134147

148+
void swift::swift_task_checkIsolated(SerialExecutorRef executor) {
149+
if (swift_task_checkIsolated_hook)
150+
swift_task_checkIsolated_hook(executor, swift_task_checkIsolatedImpl);
151+
else
152+
swift_task_checkIsolatedImpl(executor);
153+
}
154+
135155
// Implemented in Swift because we need to obtain the user-defined flags on the executor ref.
136156
//
137157
// We could inline this with effort, though.

stdlib/public/Concurrency/NonDispatchGlobalExecutor.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,10 @@ static void swift_task_enqueueMainExecutorImpl(Job *job) {
6161
swift_reportError(0, "operation unsupported without libdispatch: "
6262
"swift_task_enqueueMainExecutor");
6363
}
64+
65+
SWIFT_CC(swift)
66+
static void swift_task_checkIsolatedImpl(SerialExecutorRef executor) {
67+
_task_serialExecutor_checkIsolated(
68+
executor.getIdentity(), swift_getObjectType(executor.getIdentity()),
69+
executor.getSerialExecutorWitnessTable());
70+
}

test/Concurrency/Runtime/actor_assert_precondition_executor_checkIsolated.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
//import StdlibUnittest
2020
import Dispatch
2121

22+
// TODO: Dispatch should provide such implementation
2223
extension DispatchSerialQueue {
23-
func checkIsolated() {
24-
print("CHECK \(self)")
24+
public func checkIsolated() {
2525
dispatchPrecondition(condition: .onQueue(self))
2626
}
2727
}
@@ -46,7 +46,7 @@ final class NaiveQueueExecutor: SerialExecutor {
4646
}
4747

4848
func checkIsolated() {
49-
dispatchPrecondition(condition: .onQueue(self.queue))
49+
self.queue.checkIsolated()
5050
}
5151
}
5252

unittests/runtime/CompatibilityOverrideConcurrency.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ swift_task_enqueueGlobal_override(Job *job,
8484
Ran = true;
8585
}
8686

87+
SWIFT_CC(swift)
88+
static void
89+
swift_task_checkIsolated_override(SerialExecutorRef executor,
90+
swift_task_checkIsolated_original original) {
91+
Ran = true;
92+
}
93+
8794
SWIFT_CC(swift)
8895
static void swift_task_enqueueGlobalWithDelay_override(
8996
unsigned long long delay, Job *job,
@@ -130,6 +137,8 @@ class CompatibilityOverrideConcurrencyTest : public ::testing::Test {
130137
swift_task_enqueueGlobalWithDelay_override;
131138
swift_task_enqueueMainExecutor_hook =
132139
swift_task_enqueueMainExecutor_override;
140+
swift_task_checkIsolated_hook =
141+
swift_task_checkIsolated_override;
133142
#ifdef RUN_ASYNC_MAIN_DRAIN_QUEUE_TEST
134143
swift_task_asyncMainDrainQueue_hook =
135144
swift_task_asyncMainDrainQueue_override_fn;
@@ -182,6 +191,11 @@ TEST_F(CompatibilityOverrideConcurrencyTest,
182191
swift_task_enqueueGlobalWithDelay(0, &fakeJob);
183192
}
184193

194+
TEST_F(CompatibilityOverrideConcurrencyTest,
195+
test_swift_task_checkIsolated) {
196+
swift_task_checkIsolated(SerialExecutorRef::generic());
197+
}
198+
185199
TEST_F(CompatibilityOverrideConcurrencyTest,
186200
test_swift_task_enqueueMainExecutor) {
187201
swift_task_enqueueMainExecutor(&fakeJob);

0 commit comments

Comments
 (0)