Skip to content

Commit

Permalink
Merge pull request #3417 from Sonicadvance1/workaround_hang
Browse files Browse the repository at this point in the history
ThreadManager: StealAndDropActiveLocks in the child forked process
  • Loading branch information
Sonicadvance1 authored Feb 12, 2024
2 parents 780b486 + 67143ed commit 930d265
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 13 deletions.
10 changes: 5 additions & 5 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args
if (!AnyFlagsSet(flags, CLONE_THREAD)) {
// Has an unsupported flag
// Fall to a handler that can handle this case
auto Thread = Frame->Thread;

args->SignalMask = ~0ULL;
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &args->SignalMask, &args->SignalMask, sizeof(args->SignalMask));
Expand All @@ -590,9 +589,7 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args
args->StackSize = FEX::LinuxEmulation::Threads::STACK_SIZE;
args->NewStack = FEX::LinuxEmulation::Threads::AllocateStackObject();

Thread->CTX->LockBeforeFork(Frame->Thread);

FEX::HLE::_SyscallHandler->LockBeforeFork();
FEX::HLE::_SyscallHandler->LockBeforeFork(Frame->Thread);

uint64_t Result{};
if (args->Type == TYPE_CLONE2) {
Expand Down Expand Up @@ -829,7 +826,8 @@ uint64_t UnimplementedSyscallSafe(FEXCore::Core::CpuStateFrame *Frame, uint64_t
return -ENOSYS;
}

void SyscallHandler::LockBeforeFork() {
void SyscallHandler::LockBeforeFork(FEXCore::Core::InternalThreadState *Thread) {
Thread->CTX->LockBeforeFork(Thread);
VMATracking.Mutex.lock();
}

Expand All @@ -841,6 +839,8 @@ void SyscallHandler::UnlockAfterFork(FEXCore::Core::InternalThreadState *LiveThr
VMATracking.Mutex.unlock();
}

CTX->UnlockAfterFork(LiveThread, Child);

// Clear all the other threads that are being tracked
TM.UnlockAfterFork(LiveThread, Child);
}
Expand Down
4 changes: 2 additions & 2 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class ThreadManager final {
FEXCore::Context::Context *CTX;
FEX::HLE::SignalDelegator *SignalDelegation;

std::mutex ThreadCreationMutex;
FEXCore::ForkableUniqueMutex ThreadCreationMutex;
fextl::vector<FEXCore::Core::InternalThreadState *> Threads;

// Thread idling support.
Expand Down Expand Up @@ -303,7 +303,7 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
FEXCore::HLE::AOTIRCacheEntryLookupResult LookupAOTIRCacheEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestAddr) final override;

///// FORK tracking /////
void LockBeforeFork();
void LockBeforeFork(FEXCore::Core::InternalThreadState *Thread);
void UnlockAfterFork(FEXCore::Core::InternalThreadState *LiveThread, bool Child);

SourcecodeResolver *GetSourcecodeResolver() override { return this; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ namespace FEX::HLE {

uint64_t Mask{~0ULL};
::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &Mask, &Mask, sizeof(Mask));
Thread->CTX->LockBeforeFork(Frame->Thread);

FEX::HLE::_SyscallHandler->LockBeforeFork();
FEX::HLE::_SyscallHandler->LockBeforeFork(Frame->Thread);

const bool IsVFork = flags & CLONE_VFORK;
pid_t Result{};
Expand Down
7 changes: 3 additions & 4 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ namespace FEX::HLE {
void ThreadManager::WaitForThreadsToRun() {
size_t NumThreads{};
{
std::lock_guard<std::mutex> lk(ThreadCreationMutex);
std::lock_guard lk(ThreadCreationMutex);
NumThreads = Threads.size();
}

Expand Down Expand Up @@ -134,7 +134,7 @@ namespace FEX::HLE {

// Tell all the threads that they should stop
{
std::lock_guard<std::mutex> lk(ThreadCreationMutex);
std::lock_guard lk(ThreadCreationMutex);
for (auto &Thread : Threads) {
if (IgnoreCurrentThread &&
Thread->ThreadManager.TID == tid) {
Expand Down Expand Up @@ -185,8 +185,6 @@ namespace FEX::HLE {
}

void ThreadManager::UnlockAfterFork(FEXCore::Core::InternalThreadState *LiveThread, bool Child) {
CTX->UnlockAfterFork(LiveThread, Child);

if (!Child) return;

// This function is called after fork
Expand Down Expand Up @@ -225,6 +223,7 @@ namespace FEX::HLE {

// We now only have one thread.
IdleWaitRefCount = 1;
ThreadCreationMutex.StealAndDropActiveLocks();
}

void ThreadManager::WaitForIdle() {
Expand Down

0 comments on commit 930d265

Please sign in to comment.