17
17
#ifndef SWIFT_CONCURRENCY_TASKPRIVATE_H
18
18
#define SWIFT_CONCURRENCY_TASKPRIVATE_H
19
19
20
- #include " swift/Runtime/Concurrency.h"
21
- #include " swift/ABI/Task.h"
20
+ #include " Error.h"
22
21
#include " swift/ABI/Metadata.h"
22
+ #include " swift/ABI/Task.h"
23
23
#include " swift/Runtime/Atomic.h"
24
- #include " swift/Runtime/HeapObject .h"
24
+ #include " swift/Runtime/Concurrency .h"
25
25
#include " swift/Runtime/Error.h"
26
- #include " Error.h"
26
+ #include " swift/Runtime/Exclusivity.h"
27
+ #include " swift/Runtime/HeapObject.h"
27
28
28
29
#define SWIFT_FATAL_ERROR swift_Concurrency_fatalError
29
30
#include " ../runtime/StackAllocator.h"
@@ -282,14 +283,19 @@ struct AsyncTask::PrivateStorage {
282
283
// / Currently one word.
283
284
TaskLocal::Storage Local;
284
285
286
+ // / State inside the AsyncTask whose state is only managed by the exclusivity
287
+ // / runtime in stdlibCore. We zero initialize to provide a safe initial value,
288
+ // / but actually initialize its bit state to a const global provided by
289
+ // / libswiftCore so that libswiftCore can control the layout of our initial
290
+ // / state.
291
+ uintptr_t ExclusivityAccessSet[2 ] = {0 , 0 };
292
+
285
293
PrivateStorage (JobFlags flags)
286
- : Status(ActiveTaskStatus(flags)),
287
- Local (TaskLocal::Storage()) {}
294
+ : Status(ActiveTaskStatus(flags)), Local(TaskLocal::Storage()) {}
288
295
289
296
PrivateStorage (JobFlags flags, void *slab, size_t slabCapacity)
290
- : Status(ActiveTaskStatus(flags)),
291
- Allocator(slab, slabCapacity),
292
- Local(TaskLocal::Storage()) {}
297
+ : Status(ActiveTaskStatus(flags)), Allocator(slab, slabCapacity),
298
+ Local (TaskLocal::Storage()) {}
293
299
294
300
void complete (AsyncTask *task) {
295
301
// Destroy and deallocate any remaining task local items.
@@ -347,7 +353,10 @@ inline void AsyncTask::flagAsRunning() {
347
353
while (true ) {
348
354
assert (!oldStatus.isRunning ());
349
355
if (oldStatus.isLocked ()) {
350
- return flagAsRunning_slow ();
356
+ flagAsRunning_slow ();
357
+ swift_task_enterThreadLocalContext (
358
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
359
+ return ;
351
360
}
352
361
353
362
auto newStatus = oldStatus.withRunning (true );
@@ -358,8 +367,11 @@ inline void AsyncTask::flagAsRunning() {
358
367
359
368
if (_private ().Status .compare_exchange_weak (oldStatus, newStatus,
360
369
std::memory_order_relaxed,
361
- std::memory_order_relaxed))
370
+ std::memory_order_relaxed)) {
371
+ swift_task_enterThreadLocalContext (
372
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
362
373
return ;
374
+ }
363
375
}
364
376
}
365
377
@@ -368,7 +380,10 @@ inline void AsyncTask::flagAsSuspended() {
368
380
while (true ) {
369
381
assert (oldStatus.isRunning ());
370
382
if (oldStatus.isLocked ()) {
371
- return flagAsSuspended_slow ();
383
+ flagAsSuspended_slow ();
384
+ swift_task_exitThreadLocalContext (
385
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
386
+ return ;
372
387
}
373
388
374
389
auto newStatus = oldStatus.withRunning (false );
@@ -379,8 +394,11 @@ inline void AsyncTask::flagAsSuspended() {
379
394
380
395
if (_private ().Status .compare_exchange_weak (oldStatus, newStatus,
381
396
std::memory_order_relaxed,
382
- std::memory_order_relaxed))
397
+ std::memory_order_relaxed)) {
398
+ swift_task_exitThreadLocalContext (
399
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
383
400
return ;
401
+ }
384
402
}
385
403
}
386
404
0 commit comments