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"
22
20
#include " swift/ABI/Metadata.h"
21
+ #include " swift/ABI/Task.h"
23
22
#include " swift/Runtime/Atomic.h"
24
- #include " swift/Runtime/HeapObject .h"
23
+ #include " swift/Runtime/Concurrency .h"
25
24
#include " swift/Runtime/Error.h"
25
+ #include " swift/Runtime/Exclusivity.h"
26
+ #include " swift/Runtime/HeapObject.h"
27
+
26
28
#include " ../runtime/StackAllocator.h"
27
29
28
30
namespace swift {
@@ -255,14 +257,19 @@ struct AsyncTask::PrivateStorage {
255
257
// / Currently one word.
256
258
TaskLocal::Storage Local;
257
259
260
+ // / State inside the AsyncTask whose state is only managed by the exclusivity
261
+ // / runtime in stdlibCore. We zero initialize to provide a safe initial value,
262
+ // / but actually initialize its bit state to a const global provided by
263
+ // / libswiftCore so that libswiftCore can control the layout of our initial
264
+ // / state.
265
+ uintptr_t ExclusivityAccessSet[2 ] = {0 , 0 };
266
+
258
267
PrivateStorage (JobFlags flags)
259
- : Status(ActiveTaskStatus(flags)),
260
- Local (TaskLocal::Storage()) {}
268
+ : Status(ActiveTaskStatus(flags)), Local(TaskLocal::Storage()) {}
261
269
262
270
PrivateStorage (JobFlags flags, void *slab, size_t slabCapacity)
263
- : Status(ActiveTaskStatus(flags)),
264
- Allocator(slab, slabCapacity),
265
- Local(TaskLocal::Storage()) {}
271
+ : Status(ActiveTaskStatus(flags)), Allocator(slab, slabCapacity),
272
+ Local (TaskLocal::Storage()) {}
266
273
267
274
void complete (AsyncTask *task) {
268
275
// Destroy and deallocate any remaining task local items.
@@ -320,7 +327,10 @@ inline void AsyncTask::flagAsRunning() {
320
327
while (true ) {
321
328
assert (!oldStatus.isRunning ());
322
329
if (oldStatus.isLocked ()) {
323
- return flagAsRunning_slow ();
330
+ flagAsRunning_slow ();
331
+ swift_task_enterThreadLocalContext (
332
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
333
+ return ;
324
334
}
325
335
326
336
auto newStatus = oldStatus.withRunning (true );
@@ -331,8 +341,11 @@ inline void AsyncTask::flagAsRunning() {
331
341
332
342
if (_private ().Status .compare_exchange_weak (oldStatus, newStatus,
333
343
std::memory_order_relaxed,
334
- std::memory_order_relaxed))
344
+ std::memory_order_relaxed)) {
345
+ swift_task_enterThreadLocalContext (
346
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
335
347
return ;
348
+ }
336
349
}
337
350
}
338
351
@@ -341,7 +354,10 @@ inline void AsyncTask::flagAsSuspended() {
341
354
while (true ) {
342
355
assert (oldStatus.isRunning ());
343
356
if (oldStatus.isLocked ()) {
344
- return flagAsSuspended_slow ();
357
+ flagAsSuspended_slow ();
358
+ swift_task_exitThreadLocalContext (
359
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
360
+ return ;
345
361
}
346
362
347
363
auto newStatus = oldStatus.withRunning (false );
@@ -352,8 +368,11 @@ inline void AsyncTask::flagAsSuspended() {
352
368
353
369
if (_private ().Status .compare_exchange_weak (oldStatus, newStatus,
354
370
std::memory_order_relaxed,
355
- std::memory_order_relaxed))
371
+ std::memory_order_relaxed)) {
372
+ swift_task_exitThreadLocalContext (
373
+ (char *)&_private ().ExclusivityAccessSet [0 ]);
356
374
return ;
375
+ }
357
376
}
358
377
}
359
378
0 commit comments