mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 09:00:17 +02:00
DiskCache: on Linux, block signals in Writer thread
Clean up thread flags while we're at it.
This commit is contained in:
1 parent
e17fdf9e90
commit
c0b24b2f2e
8 files changed
+46
-30
No files matched your search
@@ -381,7 +381,8 @@ namespace DiskCache {
|
||||
}
|
||||
|
||||
if (IsWritingDiskCache()) {
|
||||
Writer = fextl::make_unique<WorkQueueThread>(true);
|
||||
FEXCore::Threads::Flags WriterThreadFlags = {.LowPriority = true, .Internal = true};
|
||||
Writer = fextl::make_unique<WorkQueueThread>(WriterThreadFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
namespace FEXCore::Threads {
|
||||
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_Default(ThreadFunc Func, void* Arg, bool LowPriority) {
|
||||
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_Default(ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags) {
|
||||
ERROR_AND_DIE_FMT("Frontend didn't setup thread creation!");
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ static FEXCore::Threads::Pointers Ptrs = {
|
||||
.CleanupAfterFork = CleanupAfterFork_Default,
|
||||
};
|
||||
|
||||
fextl::unique_ptr<FEXCore::Threads::Thread> FEXCore::Threads::Thread::Create(ThreadFunc Func, void* Arg, bool LowPriority) {
|
||||
return Ptrs.CreateThread(Func, Arg, LowPriority);
|
||||
fextl::unique_ptr<FEXCore::Threads::Thread> FEXCore::Threads::Thread::Create(ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags) {
|
||||
return Ptrs.CreateThread(Func, Arg, Flags);
|
||||
}
|
||||
|
||||
void FEXCore::Threads::Thread::CleanupAfterFork() {
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
namespace FEXCore {
|
||||
|
||||
WorkQueueThread::WorkQueueThread(bool LowPriority) {
|
||||
Thread = FEXCore::Threads::Thread::Create(ThreadEntry, this, LowPriority);
|
||||
WorkQueueThread::WorkQueueThread(FEXCore::Threads::Flags ThreadFlags) {
|
||||
Thread = FEXCore::Threads::Thread::Create(ThreadEntry, this, ThreadFlags);
|
||||
}
|
||||
|
||||
WorkQueueThread::~WorkQueueThread() {
|
||||
|
||||
@@ -4,10 +4,16 @@
|
||||
#include <FEXCore/fextl/memory.h>
|
||||
|
||||
namespace FEXCore::Threads {
|
||||
|
||||
struct Flags {
|
||||
bool LowPriority : 1 {};
|
||||
bool Internal : 1 {};
|
||||
};
|
||||
|
||||
using ThreadFunc = void* (*)(void* user_ptr);
|
||||
|
||||
class Thread;
|
||||
using CreateThreadFunc = fextl::unique_ptr<Thread> (*)(ThreadFunc Func, void* Arg, bool LowPriority);
|
||||
using CreateThreadFunc = fextl::unique_ptr<Thread> (*)(ThreadFunc Func, void* Arg, Flags Flags);
|
||||
using CleanupAfterForkFunc = void (*)();
|
||||
|
||||
struct Pointers {
|
||||
@@ -28,7 +34,7 @@ public:
|
||||
* @name Calls provided API functions
|
||||
* @{ */
|
||||
|
||||
static fextl::unique_ptr<Thread> Create(ThreadFunc Func, void* Arg, bool LowPriority = false);
|
||||
static fextl::unique_ptr<Thread> Create(ThreadFunc Func, void* Arg, Flags Flags = {});
|
||||
|
||||
static void CleanupAfterFork();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
WorkQueueThread(bool LowPriority = false);
|
||||
WorkQueueThread(FEXCore::Threads::Flags Flags = {});
|
||||
~WorkQueueThread();
|
||||
|
||||
void QueueWork(fextl::unique_ptr<WorkItem> Work);
|
||||
|
||||
@@ -1482,9 +1482,7 @@ static void* ThreadHandler(void* Arg) {
|
||||
}
|
||||
|
||||
void GdbServer::StartThread() {
|
||||
uint64_t OldMask = HLE::ThreadManager::SetSignalMask(~0ULL);
|
||||
gdbServerThread = FEXCore::Threads::Thread::Create(ThreadHandler, this);
|
||||
HLE::ThreadManager::SetSignalMask(OldMask);
|
||||
gdbServerThread = FEXCore::Threads::Thread::Create(ThreadHandler, this, {.Internal = true});
|
||||
}
|
||||
|
||||
void GdbServer::OpenListenSocket() {
|
||||
|
||||
@@ -197,11 +197,11 @@ namespace PThreads {
|
||||
|
||||
class PThread final : public FEXCore::Threads::Thread {
|
||||
public:
|
||||
PThread(StackTracker* STracker, FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority)
|
||||
PThread(StackTracker* STracker, FEXCore::Threads::ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags)
|
||||
: STracker {STracker}
|
||||
, UserFunc {Func}
|
||||
, UserArg {Arg}
|
||||
, LowPriority {LowPriority} {
|
||||
, Flags {Flags} {
|
||||
pthread_attr_t Attr {};
|
||||
Stack = STracker->AllocateStackObject();
|
||||
// pthreads allocates its dtv region behind our back and there is nothing we can do about it.
|
||||
@@ -216,7 +216,15 @@ namespace PThreads {
|
||||
// `set_tid_address` address construct. If the stack is reused before the address is set to zero, then glibc won't initialize the new thread's
|
||||
// DTV/TLS region, resulting in TLS usage crashing.
|
||||
pthread_attr_setstacksize(&Attr, PTHREAD_STACK_MIN);
|
||||
uint64_t OldMask;
|
||||
bool BlockingSignals = Flags.Internal;
|
||||
if (BlockingSignals) {
|
||||
OldMask = HLE::ThreadManager::SetSignalMask(~0ULL);
|
||||
}
|
||||
pthread_create(&Thread, &Attr, InitializeThread, this);
|
||||
if (BlockingSignals) {
|
||||
HLE::ThreadManager::SetSignalMask(OldMask);
|
||||
}
|
||||
pthread_attr_destroy(&Attr);
|
||||
}
|
||||
|
||||
@@ -260,8 +268,8 @@ namespace PThreads {
|
||||
return Stack;
|
||||
}
|
||||
|
||||
bool GetLowPriority() const {
|
||||
return LowPriority;
|
||||
FEXCore::Threads::Flags GetFlags() const {
|
||||
return Flags;
|
||||
}
|
||||
|
||||
StackTracker* GetStackTracker() const {
|
||||
@@ -294,7 +302,7 @@ namespace PThreads {
|
||||
FEXCore::Threads::ThreadFunc UserFunc;
|
||||
void* UserArg;
|
||||
void* Stack {};
|
||||
bool LowPriority {};
|
||||
FEXCore::Threads::Flags Flags {};
|
||||
|
||||
// Use FEXCore's UncheckedLongJump to avoid fortification checks.
|
||||
// This avoids a false positive since glibc does not understand stack pivots.
|
||||
@@ -313,7 +321,7 @@ namespace PThreads {
|
||||
|
||||
bool LongJumpExit {};
|
||||
|
||||
if (Thread->GetLowPriority()) {
|
||||
if (Thread->GetFlags().LowPriority) {
|
||||
setpriority(PRIO_PROCESS, FHU::Syscalls::gettid(), 19);
|
||||
}
|
||||
|
||||
@@ -366,8 +374,9 @@ namespace PThreads {
|
||||
|
||||
static StackTracker* STracker {};
|
||||
|
||||
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_PThread(FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority) {
|
||||
return fextl::make_unique<PThread>(STracker, Func, Arg, LowPriority);
|
||||
static fextl::unique_ptr<FEXCore::Threads::Thread>
|
||||
CreateThread_PThread(FEXCore::Threads::ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags) {
|
||||
return fextl::make_unique<PThread>(STracker, Func, Arg, Flags);
|
||||
}
|
||||
|
||||
static void CleanupAfterFork_PThread() {
|
||||
|
||||
@@ -13,13 +13,15 @@ namespace FEX::Windows {
|
||||
namespace WinThreadImpl {
|
||||
class Thread final : public FEXCore::Threads::Thread {
|
||||
public:
|
||||
Thread(FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority)
|
||||
Thread(FEXCore::Threads::ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags)
|
||||
: UserFunc {Func}
|
||||
, UserArg {Arg}
|
||||
, LowPriority {LowPriority} {
|
||||
, Flags {Flags} {
|
||||
// hide everything from guest, don't initialize anything, we'll do that manually in RunThread()
|
||||
const ULONG CreateFlags = THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH | THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER |
|
||||
THREAD_CREATE_FLAGS_SKIP_LOADER_INIT | THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE;
|
||||
ULONG CreateFlags = THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH | THREAD_CREATE_FLAGS_SKIP_LOADER_INIT | THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE;
|
||||
if (Flags.Internal) {
|
||||
CreateFlags |= THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER;
|
||||
}
|
||||
NTSTATUS Status = NtCreateThreadEx(&Handle, THREAD_ALL_ACCESS, nullptr, GetCurrentProcess(),
|
||||
reinterpret_cast<PRTL_THREAD_START_ROUTINE>(&Thread::RunThread), this, CreateFlags, 0, 0, 0, nullptr);
|
||||
if (Status < 0) {
|
||||
@@ -62,14 +64,14 @@ namespace WinThreadImpl {
|
||||
}
|
||||
}
|
||||
|
||||
bool GetLowPriority() const {
|
||||
return LowPriority;
|
||||
FEXCore::Threads::Flags GetFlags() const {
|
||||
return Flags;
|
||||
}
|
||||
|
||||
private:
|
||||
static void RunThread(Thread* This) {
|
||||
This->TID = GetCurrentThreadId();
|
||||
if (This->GetLowPriority()) {
|
||||
if (This->GetFlags().LowPriority) {
|
||||
LONG Priority = THREAD_BASE_PRIORITY_IDLE;
|
||||
NtSetInformationThread(NtCurrentThread(), ThreadBasePriority, &Priority, sizeof(Priority));
|
||||
}
|
||||
@@ -82,14 +84,14 @@ namespace WinThreadImpl {
|
||||
|
||||
FEXCore::Threads::ThreadFunc UserFunc;
|
||||
void* UserArg;
|
||||
bool LowPriority {};
|
||||
FEXCore::Threads::Flags Flags {};
|
||||
HANDLE Handle {};
|
||||
DWORD TID {};
|
||||
void* ReturnValue {};
|
||||
};
|
||||
|
||||
fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread(FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority) {
|
||||
return fextl::make_unique<Thread>(Func, Arg, LowPriority);
|
||||
fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread(FEXCore::Threads::ThreadFunc Func, void* Arg, FEXCore::Threads::Flags Flags) {
|
||||
return fextl::make_unique<Thread>(Func, Arg, Flags);
|
||||
}
|
||||
|
||||
void CleanupAfterFork() {}
|
||||
|
||||
Reference in new issue
Block a user