Skip to content

Priority inversion avoidance in Actor Runtime #41362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions include/swift/Reflection/ReflectionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1504,21 +1504,25 @@ class ReflectionContext

std::pair<llvm::Optional<std::string>, ActorInfo>
actorInfo(StoredPointer ActorPtr) {
using DefaultActorImpl = DefaultActorImpl<Runtime>;
if (supportsPriorityEscalation) {
return {std::string("Failure reading actor with escalation support"), {}};
}

using DefaultActorImpl = DefaultActorImpl<Runtime, ActiveActorStatusWithoutEscalation<Runtime>>;

auto ActorObj = readObj<DefaultActorImpl>(ActorPtr);
if (!ActorObj)
return {std::string("failure reading actor"), {}};

ActorInfo Info{};
Info.Flags = ActorObj->Flags;
Info.Flags = ActorObj->Status.Flags[0];

// Status is the low 3 bits of Flags. Status of 0 is Idle. Don't read
// FirstJob when idle.
auto Status = Info.Flags & 0x7;
if (Status != 0) {
// This is a JobRef which stores flags in the low bits.
Info.FirstJob = ActorObj->FirstJob & ~StoredPointer(0x3);
Info.FirstJob = ActorObj->Status.FirstJob & ~StoredPointer(0x3);
}
return {llvm::None, Info};
}
Expand Down
18 changes: 15 additions & 3 deletions include/swift/Reflection/RuntimeInternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ struct StackAllocator {
template <typename Runtime>
struct ActiveTaskStatusWithEscalation {
uint32_t Flags;
uint32_t DrainLock[(sizeof(typename Runtime::StoredPointer) == 8) ? 1 : 2];
uint32_t ExecutionLock[(sizeof(typename Runtime::StoredPointer) == 8) ? 1 : 2];
typename Runtime::StoredPointer Record;
};

Expand Down Expand Up @@ -150,10 +150,22 @@ struct FutureAsyncContextPrefix {
};

template <typename Runtime>
struct ActiveActorStatusWithEscalation {
uint32_t Flags;
uint32_t DrainLock[(sizeof(typename Runtime::StoredPointer) == 8) ? 1 : 2];
typename Runtime::StoredPointer FirstJob;
};

template <typename Runtime>
struct ActiveActorStatusWithoutEscalation {
uint32_t Flags[sizeof(typename Runtime::StoredPointer) == 8 ? 2 : 1];
typename Runtime::StoredPointer FirstJob;
};

template <typename Runtime, typename ActiveActorStatus>
struct DefaultActorImpl {
HeapObject<Runtime> HeapObject;
typename Runtime::StoredPointer FirstJob;
typename Runtime::StoredSize Flags;
ActiveActorStatus Status;
};

template <typename Runtime>
Expand Down
Loading