Skip to content

Commit

Permalink
Merge pull request #3890 from Sonicadvance1/refactor_frontend_threadm…
Browse files Browse the repository at this point in the history
…anager

FEXCore: Removes ThreadManager
  • Loading branch information
Sonicadvance1 authored Jul 26, 2024
2 parents d92b6a9 + 3b2e657 commit 403fd62
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 105 deletions.
3 changes: 0 additions & 3 deletions FEXCore/Source/Interface/Context/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,6 @@ class ContextImpl final : public FEXCore::Context::Context {
// Must be called from owning thread
static void ThreadRemoveCodeEntryFromJit(FEXCore::Core::CpuStateFrame* Frame, uint64_t GuestRIP) {
auto Thread = Frame->Thread;

LOGMAN_THROW_A_FMT(Thread->ThreadManager.GetTID() == FHU::Syscalls::gettid(), "Must be called from owning thread {}, not {}",
Thread->ThreadManager.GetTID(), FHU::Syscalls::gettid());
auto lk = GuardSignalDeferringSection(static_cast<ContextImpl*>(Thread->CTX)->CodeInvalidationMutex, Thread);

ThreadRemoveCodeEntry(Thread, GuestRIP);
Expand Down
27 changes: 7 additions & 20 deletions FEXCore/Source/Interface/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ desc: Glues Frontend, OpDispatcher and IR Opts & Compilation, LookupCache, Dispa
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/HLE/SourcecodeResolver.h>
#include <FEXCore/HLE/Linux/ThreadManagement.h>
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/Event.h>
#include <FEXCore/Utils/File.h>
Expand Down Expand Up @@ -365,14 +364,15 @@ void ContextImpl::HandleCallback(FEXCore::Core::InternalThreadState* Thread, uin

FEXCore::Context::ExitReason ContextImpl::RunUntilExit(FEXCore::Core::InternalThreadState* Thread) {
ExecutionThread(Thread);
while (true) {
auto reason = Thread->ExitReason;

// Don't return if a custom exit handling the exit
if (!CustomExitHandler || reason == ExitReason::EXIT_SHUTDOWN) {
return reason;
}
CoreShuttingDown.store(true);

if (CustomExitHandler) {
CustomExitHandler(Thread, FEXCore::Context::ExitReason::EXIT_SHUTDOWN);
return Thread->ExitReason;
}

return FEXCore::Context::ExitReason::EXIT_SHUTDOWN;
}

void ContextImpl::ExecuteThread(FEXCore::Core::InternalThreadState* Thread) {
Expand All @@ -382,9 +382,6 @@ void ContextImpl::ExecuteThread(FEXCore::Core::InternalThreadState* Thread) {

void ContextImpl::InitializeThreadTLSData(FEXCore::Core::InternalThreadState* Thread) {
// Let's do some initial bookkeeping here
Thread->ThreadManager.TID = FHU::Syscalls::gettid();
Thread->ThreadManager.PID = ::getpid();

if (ThunkHandler) {
ThunkHandler->RegisterTLSState(Thread);
}
Expand Down Expand Up @@ -438,7 +435,6 @@ ContextImpl::CreateThread(uint64_t InitialRIP, uint64_t StackPointer, FEXCore::C
}

// Set up the thread manager state
Thread->ThreadManager.parent_tid = ParentTID;
Thread->CurrentFrame->Thread = Thread;

InitializeCompiler(Thread);
Expand Down Expand Up @@ -924,15 +920,6 @@ void ContextImpl::ExecutionThread(FEXCore::Core::InternalThreadState* Thread) {
// If it is the parent thread that died then just leave
FEX_TODO("This doesn't make sense when the parent thread doesn't outlive its children");

if (Thread->ThreadManager.parent_tid == 0) {
CoreShuttingDown.store(true);
Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN;

if (CustomExitHandler) {
CustomExitHandler(Thread, Thread->ExitReason);
}
}

#ifndef _WIN32
Alloc::OSAllocator::UninstallTLSData(Thread);
#endif
Expand Down
1 change: 0 additions & 1 deletion FEXCore/include/FEXCore/Core/CoreState.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/IR/IR.h>
#include <FEXCore/HLE/Linux/ThreadManagement.h>
#include <FEXCore/Utils/CompilerDefs.h>
#include <FEXCore/Utils/Telemetry.h>

Expand Down
1 change: 0 additions & 1 deletion FEXCore/include/FEXCore/Debug/InternalThreadState.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ struct InternalThreadState : public FEXCore::Allocator::FEXAllocOperators {

NonMovableUniquePtr<FEXCore::Frontend::Decoder> FrontendDecoder;
NonMovableUniquePtr<FEXCore::IR::PassManager> PassManager;
FEXCore::HLE::ThreadManagement ThreadManager;
NonMovableUniquePtr<JITSymbolBuffer> SymbolBuffer;

int StatusCode {};
Expand Down
41 changes: 0 additions & 41 deletions FEXCore/include/FEXCore/HLE/Linux/ThreadManagement.h

This file was deleted.

13 changes: 6 additions & 7 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/GdbServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ desc: Provides a gdb interface to the guest state
#include <FEXCore/Core/SignalDelegator.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/HLE/Linux/ThreadManagement.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Utils/CompilerDefs.h>
#include <FEXCore/Utils/FileLoading.h>
Expand Down Expand Up @@ -324,7 +323,7 @@ fextl::string GdbServer::readRegs() {
bool Found = false;

for (auto& Thread : *Threads) {
if (Thread->Thread->ThreadManager.GetTID() != CurrentDebuggingThread) {
if (Thread->ThreadInfo.TID != CurrentDebuggingThread) {
continue;
}
memcpy(&state, Thread->Thread->CurrentFrame, sizeof(state));
Expand Down Expand Up @@ -375,7 +374,7 @@ GdbServer::HandledPacketType GdbServer::readReg(const fextl::string& packet) {
bool Found = false;

for (auto& Thread : *Threads) {
if (Thread->Thread->ThreadManager.GetTID() != CurrentDebuggingThread) {
if (Thread->ThreadInfo.TID != CurrentDebuggingThread) {
continue;
}
memcpy(&state, Thread->Thread->CurrentFrame, sizeof(state));
Expand Down Expand Up @@ -722,8 +721,8 @@ GdbServer::HandledPacketType GdbServer::handleXfer(const fextl::string& packet)
ss << "<threads>\n";
for (auto& Thread : *Threads) {
// Thread id is in hex without 0x prefix
const auto ThreadName = getThreadName(Thread->Thread->ThreadManager.GetTID());
ss << "<thread id=\"" << std::hex << Thread->Thread->ThreadManager.GetTID() << "\"";
const auto ThreadName = getThreadName(Thread->ThreadInfo.TID);
ss << "<thread id=\"" << std::hex << Thread->ThreadInfo.TID << "\"";
if (!ThreadName.empty()) {
ss << " name=\"" << ThreadName << "\"";
}
Expand Down Expand Up @@ -962,7 +961,7 @@ GdbServer::HandledPacketType GdbServer::handleQuery(const fextl::string& packet)
ss << "m";
for (size_t i = 0; i < Threads->size(); ++i) {
auto Thread = Threads->at(i);
ss << std::hex << Thread->Thread->ThreadManager.TID;
ss << std::hex << Thread->ThreadInfo.TID;
if (i != (Threads->size() - 1)) {
ss << ",";
}
Expand All @@ -985,7 +984,7 @@ GdbServer::HandledPacketType GdbServer::handleQuery(const fextl::string& packet)
// Returns the current Thread ID
auto Threads = SyscallHandler->TM.GetThreads();
fextl::ostringstream ss;
ss << "m" << std::hex << Threads->at(0)->Thread->ThreadManager.TID;
ss << "m" << std::hex << Threads->at(0)->ThreadInfo.TID;
return {ss.str(), HandledPacketType::TYPE_ACK};
}
if (match("QStartNoAckMode")) {
Expand Down
8 changes: 5 additions & 3 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ desc: Handles host -> host and host -> guest signal routing, emulates procmask &
#include <FEXCore/Core/SignalDelegator.h>
#include <FEXCore/Core/X86Enums.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/HLE/Linux/ThreadManagement.h>
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/LogManager.h>
#include <FEXCore/Utils/MathUtils.h>
Expand Down Expand Up @@ -1299,12 +1298,13 @@ bool SignalDelegator::HandleSignalPause(FEXCore::Core::InternalThreadState* Thre
}

void SignalDelegator::SignalThread(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::SignalEvent Event) {
auto ThreadObject = static_cast<const FEX::HLE::ThreadStateObject*>(Thread->FrontendPtr);
if (Event == FEXCore::Core::SignalEvent::Pause && Thread->RunningEvents.Running.load() == false) {
// Skip signaling a thread if it is already paused.
return;
}
Thread->SignalReason.store(Event);
FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, SignalDelegator::SIGNAL_FOR_PAUSE);
FHU::Syscalls::tgkill(ThreadObject->ThreadInfo.PID, ThreadObject->ThreadInfo.TID, SignalDelegator::SIGNAL_FOR_PAUSE);
}

/** @} */
Expand Down Expand Up @@ -1897,12 +1897,14 @@ uint64_t SignalDelegator::RegisterGuestSigAltStack(const stack_t* ss, stack_t* o
}

static void CheckForPendingSignals(FEXCore::Core::InternalThreadState* Thread) {
auto ThreadObject = static_cast<const FEX::HLE::ThreadStateObject*>(Thread->FrontendPtr);

// Do we have any pending signals that became unmasked?
uint64_t PendingSignals = ~ThreadData.CurrentSignalMask.Val & ThreadData.PendingSignals;
if (PendingSignals != 0) {
for (int i = 0; i < 64; ++i) {
if (PendingSignals & (1ULL << i)) {
FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, i + 1);
FHU::Syscalls::tgkill(ThreadObject->ThreadInfo.PID, ThreadObject->ThreadInfo.TID, i + 1);
// We might not even return here which is spooky
}
}
Expand Down
3 changes: 1 addition & 2 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ desc: Glue logic, brk allocations
#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/CoreState.h>
#include <FEXCore/Debug/InternalThreadState.h>
#include <FEXCore/HLE/Linux/ThreadManagement.h>
#include <FEXCore/HLE/SyscallHandler.h>
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/CompilerDefs.h>
Expand Down Expand Up @@ -629,7 +628,7 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::clone3_args
auto NewThread = FEX::HLE::CreateNewThread(Thread->CTX, Frame, args);

// Return the new threads TID
uint64_t Result = NewThread->Thread->ThreadManager.GetTID();
uint64_t Result = NewThread->ThreadInfo.TID;

// Actually start the thread
FEX::HLE::_SyscallHandler->TM.RunThread(NewThread);
Expand Down
43 changes: 24 additions & 19 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ static void* ThreadHandler(void* Data) {
auto CTX = Handler->CTX;
auto Thread = Handler->Thread;
FEXCore::Allocator::free(Handler);

Thread->ThreadInfo.PID = ::getpid();
Thread->ThreadInfo.TID = FHU::Syscalls::gettid();

FEX::HLE::_SyscallHandler->GetSignalDelegator()->RegisterTLSState(Thread);
CTX->ExecutionThread(Thread->Thread);
FEX::HLE::_SyscallHandler->GetSignalDelegator()->UninstallTLSState(Thread);
Expand Down Expand Up @@ -111,7 +115,7 @@ FEX::HLE::ThreadStateObject* CreateNewThread(FEXCore::Context::Context* CTX, FEX
}

// Return the new threads TID
uint64_t Result = NewThread->Thread->ThreadManager.GetTID();
uint64_t Result = NewThread->ThreadInfo.TID;

// Sets the child TID to pointer in ParentTID
if (flags & CLONE_PARENT_SETTID) {
Expand All @@ -120,15 +124,15 @@ FEX::HLE::ThreadStateObject* CreateNewThread(FEXCore::Context::Context* CTX, FEX

// Sets the child TID to the pointer in ChildTID
if (flags & CLONE_CHILD_SETTID) {
NewThread->Thread->ThreadManager.set_child_tid = reinterpret_cast<int32_t*>(args->args.child_tid);
NewThread->ThreadInfo.set_child_tid = reinterpret_cast<int32_t*>(args->args.child_tid);
*reinterpret_cast<pid_t*>(args->args.child_tid) = Result;
}

// When the thread exits, clear the child thread ID at ChildTID
// Additionally wakeup a futex at that address
// Address /may/ be changed with SET_TID_ADDRESS syscall
if (flags & CLONE_CHILD_CLEARTID) {
NewThread->Thread->ThreadManager.clear_child_tid = reinterpret_cast<int32_t*>(args->args.child_tid);
NewThread->ThreadInfo.clear_child_tid = reinterpret_cast<int32_t*>(args->args.child_tid);
}

// clone3 flag
Expand Down Expand Up @@ -209,9 +213,9 @@ uint64_t HandleNewClone(FEX::HLE::ThreadStateObject* Thread, FEXCore::Context::C
}

// Depending on clone settings, our TID and PID could have changed
Thread->Thread->ThreadManager.TID = FHU::Syscalls::gettid();
Thread->Thread->ThreadManager.PID = ::getpid();
FEX::HLE::_SyscallHandler->FM.UpdatePID(Thread->Thread->ThreadManager.PID);
Thread->ThreadInfo.TID = FHU::Syscalls::gettid();
Thread->ThreadInfo.PID = ::getpid();
FEX::HLE::_SyscallHandler->FM.UpdatePID(Thread->ThreadInfo.PID);

if (CreatedNewThreadObject) {
FEX::HLE::_SyscallHandler->TM.TrackThread(Thread);
Expand Down Expand Up @@ -265,17 +269,18 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp
const bool IsChild = Result == 0;

if (IsChild) {
auto ThreadObject = static_cast<FEX::HLE::ThreadStateObject*>(Thread->FrontendPtr);
// Unlock the mutexes on both sides of the fork
FEX::HLE::_SyscallHandler->UnlockAfterFork(Frame->Thread, IsChild);

::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &Mask, nullptr, sizeof(Mask));

// Child
// update the internal TID
Thread->ThreadManager.TID = FHU::Syscalls::gettid();
Thread->ThreadManager.PID = ::getpid();
FEX::HLE::_SyscallHandler->FM.UpdatePID(Thread->ThreadManager.PID);
Thread->ThreadManager.clear_child_tid = nullptr;
ThreadObject->ThreadInfo.TID = FHU::Syscalls::gettid();
ThreadObject->ThreadInfo.PID = ::getpid();
FEX::HLE::_SyscallHandler->FM.UpdatePID(ThreadObject->ThreadInfo.PID);
ThreadObject->ThreadInfo.clear_child_tid = nullptr;

// only a single thread running so no need to remove anything from the thread array

Expand All @@ -301,15 +306,15 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp

// Sets the child TID to the pointer in ChildTID
if (flags & CLONE_CHILD_SETTID) {
Thread->ThreadManager.set_child_tid = child_tid;
*child_tid = Thread->ThreadManager.TID;
ThreadObject->ThreadInfo.set_child_tid = child_tid;
*child_tid = ThreadObject->ThreadInfo.TID;
}

// When the thread exits, clear the child thread ID at ChildTID
// Additionally wakeup a futex at that address
// Address /may/ be changed with SET_TID_ADDRESS syscall
if (flags & CLONE_CHILD_CLEARTID) {
Thread->ThreadManager.clear_child_tid = child_tid;
ThreadObject->ThreadInfo.clear_child_tid = child_tid;
}

// the rest of the context remains as is, this thread will keep executing
Expand Down Expand Up @@ -387,10 +392,10 @@ void RegisterThread(FEX::HLE::SyscallHandler* Handler) {
FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator::HardDisable();
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);

if (Thread->ThreadManager.clear_child_tid) {
std::atomic<uint32_t>* Addr = reinterpret_cast<std::atomic<uint32_t>*>(Thread->ThreadManager.clear_child_tid);
if (ThreadObject->ThreadInfo.clear_child_tid) {
std::atomic<uint32_t>* Addr = reinterpret_cast<std::atomic<uint32_t>*>(ThreadObject->ThreadInfo.clear_child_tid);
Addr->store(0);
syscall(SYSCALL_DEF(futex), Thread->ThreadManager.clear_child_tid, FUTEX_WAKE, ~0ULL, 0, 0, 0);
syscall(SYSCALL_DEF(futex), ThreadObject->ThreadInfo.clear_child_tid, FUTEX_WAKE, ~0ULL, 0, 0, 0);
}

Thread->StatusCode = status;
Expand Down Expand Up @@ -481,9 +486,9 @@ void RegisterThread(FEX::HLE::SyscallHandler* Handler) {

REGISTER_SYSCALL_IMPL_FLAGS(set_tid_address, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame* Frame, int* tidptr) -> uint64_t {
auto Thread = Frame->Thread;
Thread->ThreadManager.clear_child_tid = tidptr;
return Thread->ThreadManager.GetTID();
auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame);
ThreadObject->ThreadInfo.clear_child_tid = tidptr;
return ThreadObject->ThreadInfo.TID;
});

REGISTER_SYSCALL_IMPL_FLAGS(exit_group, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY | SyscallFlags::NORETURN,
Expand Down
12 changes: 10 additions & 2 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ namespace FEX::HLE {
FEX::HLE::ThreadStateObject*
ThreadManager::CreateThread(uint64_t InitialRIP, uint64_t StackPointer, FEXCore::Core::CPUState* NewThreadState, uint64_t ParentTID) {
auto ThreadStateObject = new FEX::HLE::ThreadStateObject;

ThreadStateObject->ThreadInfo.parent_tid = ParentTID;
ThreadStateObject->ThreadInfo.PID = ::getpid();

if (ParentTID == 0) {
ThreadStateObject->ThreadInfo.TID = FHU::Syscalls::gettid();
}

ThreadStateObject->Thread = CTX->CreateThread(InitialRIP, StackPointer, NewThreadState, ParentTID);
ThreadStateObject->Thread->FrontendPtr = ThreadStateObject;

Expand Down Expand Up @@ -135,10 +143,10 @@ void ThreadManager::Stop(bool IgnoreCurrentThread) {
{
std::lock_guard lk(ThreadCreationMutex);
for (auto& Thread : Threads) {
if (IgnoreCurrentThread && Thread->Thread->ThreadManager.TID == tid) {
if (IgnoreCurrentThread && Thread->ThreadInfo.TID == tid) {
// If we are callign stop from the current thread then we can ignore sending signals to this thread
// This means that this thread is already gone
} else if (Thread->Thread->ThreadManager.TID == tid) {
} else if (Thread->ThreadInfo.TID == tid) {
// We need to save the current thread for last to ensure all threads receive their stop signals
CurrentThread = Thread;
continue;
Expand Down
Loading

0 comments on commit 403fd62

Please sign in to comment.