DiskCache: make Writer thread low-priority

This commit is contained in:
Pierre-Loup A. Griffais committed 2026-08-23 14:01:32 -07:00
1 parent af9b438eec
commit c3fb6ccaaa
7 files changed
+39 -17

No files matched your search

+1 -1
View File
@@ -316,7 +316,7 @@ namespace DiskCache {
}
if (IsWritingDiskCache()) {
Writer = fextl::make_unique<WorkQueueThread>();
Writer = fextl::make_unique<WorkQueueThread>(true);
}
}
+3 -3
View File
@@ -7,7 +7,7 @@
#include <unistd.h>
namespace FEXCore::Threads {
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_Default(ThreadFunc Func, void* Arg) {
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_Default(ThreadFunc Func, void* Arg, bool LowPriority) {
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) {
return Ptrs.CreateThread(Func, Arg);
fextl::unique_ptr<FEXCore::Threads::Thread> FEXCore::Threads::Thread::Create(ThreadFunc Func, void* Arg, bool LowPriority) {
return Ptrs.CreateThread(Func, Arg, LowPriority);
}
void FEXCore::Threads::Thread::CleanupAfterFork() {
+2 -2
View File
@@ -4,8 +4,8 @@
namespace FEXCore {
WorkQueueThread::WorkQueueThread() {
Thread = FEXCore::Threads::Thread::Create(ThreadEntry, this);
WorkQueueThread::WorkQueueThread(bool LowPriority) {
Thread = FEXCore::Threads::Thread::Create(ThreadEntry, this, LowPriority);
}
WorkQueueThread::~WorkQueueThread() {
+2 -2
View File
@@ -7,7 +7,7 @@ namespace FEXCore::Threads {
using ThreadFunc = void* (*)(void* user_ptr);
class Thread;
using CreateThreadFunc = fextl::unique_ptr<Thread> (*)(ThreadFunc Func, void* Arg);
using CreateThreadFunc = fextl::unique_ptr<Thread> (*)(ThreadFunc Func, void* Arg, bool LowPriority);
using CleanupAfterForkFunc = void (*)();
struct Pointers {
@@ -28,7 +28,7 @@ public:
* @name Calls provided API functions
* @{ */
static fextl::unique_ptr<Thread> Create(ThreadFunc Func, void* Arg);
static fextl::unique_ptr<Thread> Create(ThreadFunc Func, void* Arg, bool LowPriority = false);
static void CleanupAfterFork();
@@ -18,7 +18,7 @@ public:
virtual void Run() = 0;
};
WorkQueueThread();
WorkQueueThread(bool LowPriority = false);
~WorkQueueThread();
void QueueWork(fextl::unique_ptr<WorkItem> Work);
@@ -6,6 +6,8 @@
#include <FEXCore/Utils/Allocator.h>
#include <FEXCore/Utils/LongJump.h>
#include <FEXCore/Utils/Threads.h>
#include <FEXHeaderUtils/Syscalls.h>
#include <sys/resource.h>
namespace FEX::LinuxEmulation::Threads {
void* StackTracker::AllocateStackObject() {
@@ -195,10 +197,11 @@ namespace PThreads {
class PThread final : public FEXCore::Threads::Thread {
public:
PThread(StackTracker* STracker, FEXCore::Threads::ThreadFunc Func, void* Arg)
PThread(StackTracker* STracker, FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority)
: STracker {STracker}
, UserFunc {Func}
, UserArg {Arg} {
, UserArg {Arg}
, LowPriority {LowPriority} {
pthread_attr_t Attr {};
Stack = STracker->AllocateStackObject();
// pthreads allocates its dtv region behind our back and there is nothing we can do about it.
@@ -257,6 +260,10 @@ namespace PThreads {
return Stack;
}
bool GetLowPriority() const {
return LowPriority;
}
StackTracker* GetStackTracker() const {
return STracker;
}
@@ -287,6 +294,7 @@ namespace PThreads {
FEXCore::Threads::ThreadFunc UserFunc;
void* UserArg;
void* Stack {};
bool LowPriority {};
// Use FEXCore's UncheckedLongJump to avoid fortification checks.
// This avoids a false positive since glibc does not understand stack pivots.
@@ -305,6 +313,10 @@ namespace PThreads {
bool LongJumpExit {};
if (Thread->GetLowPriority()) {
setpriority(PRIO_PROCESS, FHU::Syscalls::gettid(), 19);
}
if (FEXCore::UncheckedLongJump::SetJump(exit_resolver) == 0) {
Thread->SetupLongJump(&exit_resolver);
// Run the user function.
@@ -354,8 +366,8 @@ namespace PThreads {
static StackTracker* STracker {};
static fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread_PThread(FEXCore::Threads::ThreadFunc Func, void* Arg) {
return fextl::make_unique<PThread>(STracker, Func, Arg);
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 void CleanupAfterFork_PThread() {
+14 -4
View File
@@ -13,9 +13,10 @@ namespace FEX::Windows {
namespace WinThreadImpl {
class Thread final : public FEXCore::Threads::Thread {
public:
Thread(FEXCore::Threads::ThreadFunc Func, void* Arg)
Thread(FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority)
: UserFunc {Func}
, UserArg {Arg} {
, UserArg {Arg}
, LowPriority {LowPriority} {
// 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;
@@ -61,9 +62,17 @@ namespace WinThreadImpl {
}
}
bool GetLowPriority() const {
return LowPriority;
}
private:
static void RunThread(Thread* This) {
This->TID = GetCurrentThreadId();
if (This->GetLowPriority()) {
LONG Priority = THREAD_BASE_PRIORITY_IDLE;
NtSetInformationThread(NtCurrentThread(), ThreadBasePriority, &Priority, sizeof(Priority));
}
// do initialization we skipped earlier here around the user entrypoint
FEX::Windows::InitCRTThread();
This->ReturnValue = This->UserFunc(This->UserArg);
@@ -73,13 +82,14 @@ namespace WinThreadImpl {
FEXCore::Threads::ThreadFunc UserFunc;
void* UserArg;
bool LowPriority {};
HANDLE Handle {};
DWORD TID {};
void* ReturnValue {};
};
fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread(FEXCore::Threads::ThreadFunc Func, void* Arg) {
return fextl::make_unique<Thread>(Func, Arg);
fextl::unique_ptr<FEXCore::Threads::Thread> CreateThread(FEXCore::Threads::ThreadFunc Func, void* Arg, bool LowPriority) {
return fextl::make_unique<Thread>(Func, Arg, LowPriority);
}
void CleanupAfterFork() {}