|
29 | 29 | #include "swift/Runtime/Error.h" |
30 | 30 | #include "swift/Runtime/Exclusivity.h" |
31 | 31 | #include "swift/Runtime/HeapObject.h" |
| 32 | +#include "swift/Threading/Mutex.h" |
32 | 33 | #include "swift/Threading/Thread.h" |
33 | 34 | #include "swift/Threading/ThreadSanitizer.h" |
34 | 35 | #include <atomic> |
@@ -598,27 +599,25 @@ class alignas(2 * sizeof(void*)) ActiveTaskStatus { |
598 | 599 | #endif |
599 | 600 | } |
600 | 601 |
|
601 | | - /// Is there a lock on the linked list of status records? |
| 602 | + /// Does some thread hold the status record lock? |
602 | 603 | bool isStatusRecordLocked() const { return Flags & IsStatusRecordLocked; } |
603 | | - ActiveTaskStatus withLockingRecord(TaskStatusRecord *lockRecord) const { |
| 604 | + ActiveTaskStatus withStatusRecordLocked() const { |
604 | 605 | assert(!isStatusRecordLocked()); |
605 | | - assert(lockRecord->Parent == Record); |
606 | 606 | #if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION |
607 | | - return ActiveTaskStatus(lockRecord, Flags | IsStatusRecordLocked, ExecutionLock); |
| 607 | + return ActiveTaskStatus(Record, Flags | IsStatusRecordLocked, |
| 608 | + ExecutionLock); |
608 | 609 | #else |
609 | | - return ActiveTaskStatus(lockRecord, Flags | IsStatusRecordLocked); |
| 610 | + return ActiveTaskStatus(Record, Flags | IsStatusRecordLocked); |
610 | 611 | #endif |
611 | 612 | } |
612 | | - ActiveTaskStatus withoutLockingRecord() const { |
| 613 | + ActiveTaskStatus withoutStatusRecordLocked() const { |
613 | 614 | assert(isStatusRecordLocked()); |
614 | | - assert(Record->getKind() == TaskStatusRecordKind::Private_RecordLock); |
615 | 615 |
|
616 | | - // Remove the lock record, and put the next one as the head |
617 | | - auto newRecord = Record->Parent; |
618 | 616 | #if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION |
619 | | - return ActiveTaskStatus(newRecord, Flags & ~IsStatusRecordLocked, ExecutionLock); |
| 617 | + return ActiveTaskStatus(Record, Flags & ~IsStatusRecordLocked, |
| 618 | + ExecutionLock); |
620 | 619 | #else |
621 | | - return ActiveTaskStatus(newRecord, Flags & ~IsStatusRecordLocked); |
| 620 | + return ActiveTaskStatus(Record, Flags & ~IsStatusRecordLocked); |
622 | 621 | #endif |
623 | 622 | } |
624 | 623 |
|
@@ -779,6 +778,9 @@ struct AsyncTask::PrivateStorage { |
779 | 778 | /// async task stack when it is needed. |
780 | 779 | TaskDependencyStatusRecord *dependencyRecord = nullptr; |
781 | 780 |
|
| 781 | + // The lock used to protect more complicated operations on the task status. |
| 782 | + RecursiveMutex statusLock; |
| 783 | + |
782 | 784 | // Always create an async task with max priority in ActiveTaskStatus = base |
783 | 785 | // priority. It will be updated later if needed. |
784 | 786 | PrivateStorage(JobPriority basePri) |
|
0 commit comments