Skip to content

Commit ff10907

Browse files
committed
Change ActiveTaskStatus layout in order to be able to track the identity
of the thread that is executing the task. Radar-Id: rdar://problem/76127624
1 parent 90bf377 commit ff10907

File tree

7 files changed

+233
-40
lines changed

7 files changed

+233
-40
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class ReflectionContext
106106
typename super::StoredPointer target_future_adapter = 0;
107107
typename super::StoredPointer target_task_wait_throwing_resume_adapter = 0;
108108
typename super::StoredPointer target_task_future_wait_resume_adapter = 0;
109+
bool supportsPriorityEscalation = false;
109110

110111
public:
111112
using super::getBuilder;
@@ -164,7 +165,7 @@ class ReflectionContext
164165

165166
ReflectionContext(const ReflectionContext &other) = delete;
166167
ReflectionContext &operator=(const ReflectionContext &other) = delete;
167-
168+
168169
MemoryReader &getReader() {
169170
return *this->Reader;
170171
}
@@ -367,7 +368,7 @@ class ReflectionContext
367368

368369
auto Begin = RemoteRef<void>(Addr, BufStart);
369370
auto Size = COFFSec->VirtualSize;
370-
371+
371372
// FIXME: This code needs to be cleaned up and updated
372373
// to make it work for 32 bit platforms.
373374
Begin = Begin.atByteOffset(8);
@@ -605,7 +606,7 @@ class ReflectionContext
605606
}
606607

607608
/// Parses metadata information from an ELF image. Because the Section
608-
/// Header Table maybe be missing (for example, when reading from a
609+
/// Header Table maybe be missing (for example, when reading from a
609610
/// process) this method optionally receives a buffer with the contents
610611
/// of the image's file, from where it will the necessary information.
611612
///
@@ -652,19 +653,19 @@ class ReflectionContext
652653
auto Magic = this->getReader().readBytes(ImageStart, sizeof(uint32_t));
653654
if (!Magic)
654655
return false;
655-
656+
656657
uint32_t MagicWord;
657658
memcpy(&MagicWord, Magic.get(), sizeof(MagicWord));
658-
659+
659660
// 32- and 64-bit Mach-O.
660661
if (MagicWord == llvm::MachO::MH_MAGIC) {
661662
return readMachOSections<MachOTraits<4>>(ImageStart);
662663
}
663-
664+
664665
if (MagicWord == llvm::MachO::MH_MAGIC_64) {
665666
return readMachOSections<MachOTraits<8>>(ImageStart);
666667
}
667-
668+
668669
// PE. (This just checks for the DOS header; `readPECOFF` will further
669670
// validate the existence of the PE header.)
670671
auto MagicBytes = (const char*)Magic.get();
@@ -739,7 +740,7 @@ class ReflectionContext
739740
return true;
740741
return ownsAddress(RemoteAddress(*MetadataAddress));
741742
}
742-
743+
743744
/// Returns true if the address falls within a registered image.
744745
bool ownsAddressRaw(RemoteAddress Address) {
745746
for (auto Range : imageRanges) {
@@ -1214,7 +1215,7 @@ class ReflectionContext
12141215
}
12151216
return llvm::None;
12161217
}
1217-
1218+
12181219
/// Fetch the metadata pointer from a metadata allocation, or 0 if this
12191220
/// allocation's tag is not handled or an error occurred.
12201221
StoredPointer allocationMetadataPointer(
@@ -1312,7 +1313,7 @@ class ReflectionContext
13121313
getReader().readPointer(AllocationPoolAddrAddr, sizeof(StoredPointer));
13131314
if (!AllocationPoolAddr)
13141315
return "failed to read value of " + AllocationPoolPointerName;
1315-
1316+
13161317
struct PoolRange {
13171318
StoredPointer Begin;
13181319
StoredSize Remaining;
@@ -1358,10 +1359,10 @@ class ReflectionContext
13581359
Allocation.Ptr = RemoteAddr;
13591360
Allocation.Size = Header->Size;
13601361
Call(Allocation);
1361-
1362+
13621363
Offset += sizeof(AllocationHeader) + Header->Size;
13631364
}
1364-
1365+
13651366
TrailerPtr = Trailer->PrevTrailer;
13661367
}
13671368
return llvm::None;
@@ -1442,13 +1443,20 @@ class ReflectionContext
14421443

14431444
std::pair<llvm::Optional<std::string>, AsyncTaskInfo>
14441445
asyncTaskInfo(StoredPointer AsyncTaskPtr) {
1445-
auto AsyncTaskObj = readObj<AsyncTask<Runtime>>(AsyncTaskPtr);
1446+
loadTargetPointers();
1447+
1448+
if (supportsPriorityEscalation) {
1449+
return {std::string("Failure reading async task with escalation support"), {}};
1450+
}
1451+
1452+
using AsyncTask = AsyncTask<Runtime, ActiveTaskStatusWithoutEscalation<Runtime>>;
1453+
auto AsyncTaskObj = readObj<AsyncTask>(AsyncTaskPtr);
14461454
if (!AsyncTaskObj)
14471455
return {std::string("failure reading async task"), {}};
14481456

14491457
AsyncTaskInfo Info{};
14501458
Info.JobFlags = AsyncTaskObj->Flags;
1451-
Info.TaskStatusFlags = AsyncTaskObj->PrivateStorage.Status.Flags;
1459+
Info.TaskStatusFlags = AsyncTaskObj->PrivateStorage.Status.Flags[0];
14521460
Info.Id =
14531461
AsyncTaskObj->Id | ((uint64_t)AsyncTaskObj->PrivateStorage.Id << 32);
14541462
Info.AllocatorSlabPtr = AsyncTaskObj->PrivateStorage.Allocator.FirstSlab;
@@ -1482,7 +1490,7 @@ class ReflectionContext
14821490
Info.ChildTasks.push_back(ChildTask);
14831491

14841492
StoredPointer ChildFragmentAddr =
1485-
ChildTask + sizeof(AsyncTask<Runtime>);
1493+
ChildTask + sizeof(AsyncTask);
14861494
auto ChildFragmentObj =
14871495
readObj<ChildFragment<Runtime>>(ChildFragmentAddr);
14881496
if (ChildFragmentObj)
@@ -1499,8 +1507,8 @@ class ReflectionContext
14991507
// that's available.
15001508
int IsCancelledFlag = 0x100;
15011509
int IsRunningFlag = 0x800;
1502-
if (!(AsyncTaskObj->PrivateStorage.Status.Flags & IsCancelledFlag) &&
1503-
!(AsyncTaskObj->PrivateStorage.Status.Flags & IsRunningFlag)) {
1510+
if (!(AsyncTaskObj->PrivateStorage.Status.Flags[0] & IsCancelledFlag) &&
1511+
!(AsyncTaskObj->PrivateStorage.Status.Flags[0] & IsRunningFlag)) {
15041512
auto ResumeContext = AsyncTaskObj->ResumeContextAndReserved[0];
15051513
while (ResumeContext) {
15061514
auto ResumeContextObj = readObj<AsyncContext<Runtime>>(ResumeContext);
@@ -1551,7 +1559,7 @@ class ReflectionContext
15511559
private:
15521560
// Get the most human meaningful "run job" function pointer from the task,
15531561
// like AsyncTask::getResumeFunctionForLogging does.
1554-
StoredPointer getRunJob(const AsyncTask<Runtime> *AsyncTaskObj) {
1562+
StoredPointer getRunJob(const AsyncTask<Runtime, ActiveTaskStatusWithoutEscalation<Runtime>> *AsyncTaskObj) {
15551563
auto Fptr = stripSignedPointer(AsyncTaskObj->RunJob);
15561564

15571565
loadTargetPointers();
@@ -1610,6 +1618,11 @@ class ReflectionContext
16101618
getFunc("_swift_concurrency_debug_task_wait_throwing_resume_adapter");
16111619
target_task_future_wait_resume_adapter =
16121620
getFunc("_swift_concurrency_debug_task_future_wait_resume_adapter");
1621+
auto supportsPriorityEscalationAddr = getReader().getSymbolAddress("_swift_concurrency_debug_supportsPriorityEscalation");
1622+
if (supportsPriorityEscalationAddr) {
1623+
getReader().readInteger(supportsPriorityEscalationAddr, &supportsPriorityEscalation);
1624+
}
1625+
16131626
setupTargetPointers = true;
16141627
}
16151628

include/swift/Reflection/RuntimeInternals.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,34 @@ struct StackAllocator {
9494
};
9595

9696
template <typename Runtime>
97-
struct ActiveTaskStatus {
97+
struct ActiveTaskStatusWithEscalation {
98+
uint32_t Flags;
99+
uint32_t DrainLock[(sizeof(typename Runtime::StoredPointer) == 8) ? 1 : 2];
98100
typename Runtime::StoredPointer Record;
99-
typename Runtime::StoredSize Flags;
100101
};
101102

102103
template <typename Runtime>
104+
struct ActiveTaskStatusWithoutEscalation {
105+
uint32_t Flags[sizeof(typename Runtime::StoredPointer) == 8 ? 2 : 1];
106+
typename Runtime::StoredPointer Record;
107+
};
108+
109+
template <typename Runtime, typename ActiveTaskStatus>
103110
struct AsyncTaskPrivateStorage {
104-
ActiveTaskStatus<Runtime> Status;
111+
ActiveTaskStatus Status;
105112
StackAllocator<Runtime> Allocator;
106113
typename Runtime::StoredPointer Local;
107114
typename Runtime::StoredPointer ExclusivityAccessSet[2];
108115
uint32_t Id;
109116
};
110117

111-
template <typename Runtime>
118+
template <typename Runtime, typename ActiveTaskStatus>
112119
struct AsyncTask: Job<Runtime> {
113-
// On 64-bit, there's a Reserved64 after ResumeContext.
120+
// On 64-bit, there's a Reserved64 after ResumeContext.
114121
typename Runtime::StoredPointer ResumeContextAndReserved[
115122
sizeof(typename Runtime::StoredPointer) == 8 ? 2 : 1];
116-
117123
union {
118-
AsyncTaskPrivateStorage<Runtime> PrivateStorage;
124+
AsyncTaskPrivateStorage<Runtime, ActiveTaskStatus> PrivateStorage;
119125
typename Runtime::StoredPointer PrivateStorageRaw[14];
120126
};
121127
};

include/swift/Runtime/Concurrency.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
#endif
4242
#endif
4343

44+
// Does the runtime provide priority escalation support?
45+
#ifndef SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
46+
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH && \
47+
__has_include(<dispatch/swift_concurrency_private.h>) && __APPLE__ && \
48+
SWIFT_POINTER_IS_8_BYTES
49+
#define SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION 1
50+
#else
51+
#define SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION 0
52+
#endif
53+
#endif /* SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION */
54+
4455
namespace swift {
4556
class DefaultActor;
4657
class TaskOptionRecord;

stdlib/public/Concurrency/Debug.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ const void *const _swift_concurrency_debug_task_wait_throwing_resume_adapter;
4545
SWIFT_EXPORT_FROM(swift_Concurrency)
4646
const void *const _swift_concurrency_debug_task_future_wait_resume_adapter;
4747

48+
/// Whether the runtime we are inspecting supports priority escalation
49+
SWIFT_EXPORT_FROM(swift_Concurrency)
50+
bool _swift_concurrency_debug_supportsPriorityEscalation;
51+
4852
} // namespace swift
4953

5054
#endif

stdlib/public/Concurrency/Task.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "Tracing.h"
2828
#include "Debug.h"
2929
#include "Error.h"
30+
#include <atomic>
3031

3132
#if SWIFT_CONCURRENCY_ENABLE_DISPATCH
3233
#include <dispatch/dispatch.h>
@@ -73,6 +74,9 @@ Metadata swift::TaskAllocatorSlabMetadata;
7374
const void *const swift::_swift_concurrency_debug_asyncTaskSlabMetadata =
7475
&TaskAllocatorSlabMetadata;
7576

77+
bool swift::_swift_concurrency_debug_supportsPriorityEscalation =
78+
SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION;
79+
7680
void FutureFragment::destroy() {
7781
auto queueHead = waitQueue.load(std::memory_order_acquire);
7882
switch (queueHead.getStatus()) {

0 commit comments

Comments
 (0)