Browse Source

[core/hle/kernel] coalesce TLS from KernelCore to reduce query times

Signed-off-by: lizzie <lizzie@eden-emu.dev>
pull/3283/head
lizzie 1 month ago
parent
commit
ad79711d18
  1. 64
      src/core/hle/kernel/kernel.cpp

64
src/core/hle/kernel/kernel.cpp

@ -50,13 +50,26 @@
namespace Kernel {
// Can only be used by a single implementation PER THREAD
static thread_local struct ThreadLocalData {
std::optional<KThread> raw_thread;
KThread* current_thread = nullptr;
KThread* thread = nullptr;
u8 host_thread_id = UINT8_MAX;
bool is_phantom_mode_for_singlecore = false;
bool lock = false;
} static_tls_data = {};
struct KernelCore::Impl {
static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000;
static constexpr size_t SystemMemoryBlockSlabHeapSize = 10000;
static constexpr size_t BlockInfoSlabHeapSize = 4000;
static constexpr size_t ReservedDynamicPageCount = 64;
explicit Impl(Core::System& system_, KernelCore& kernel_) : system{system_} {}
explicit Impl(Core::System& system_, KernelCore& kernel_) : system{system_}, tls_data{static_tls_data} {
ASSERT(tls_data.lock == false);
tls_data.lock = true;
}
void SetMulticore(bool is_multi) {
is_multicore = is_multi;
@ -69,8 +82,6 @@ struct KernelCore::Impl {
global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
is_phantom_mode_for_singlecore = false;
// Derive the initial memory layout from the emulated board
Init::InitializeSlabResourceCounts(kernel);
DeriveInitialMemoryLayout();
@ -356,33 +367,34 @@ struct KernelCore::Impl {
application_process->Open();
}
static inline thread_local u8 host_thread_id = UINT8_MAX;
/// Sets the host thread ID for the caller.
u32 SetHostThreadId(std::size_t core_id) {
// This should only be called during core init.
ASSERT(host_thread_id == UINT8_MAX);
ASSERT(tls_data.host_thread_id == UINT8_MAX);
// The first four slots are reserved for CPU core threads
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u8>(core_id);
return host_thread_id;
tls_data.host_thread_id = u8(core_id);
return tls_data.host_thread_id;
}
/// Gets the host thread ID for the caller
u32 GetHostThreadId() const {
return host_thread_id;
return tls_data.host_thread_id;
}
// Gets the dummy KThread for the caller, allocating a new one if this is the first time
KThread* GetHostDummyThread(KThread* existing_thread) {
const auto initialize{[](KThread* thread) {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
return thread;
}};
thread_local KThread raw_thread{system.Kernel()};
thread_local KThread* thread = existing_thread ? existing_thread : initialize(&raw_thread);
return thread;
if (tls_data.thread == nullptr) {
auto const initialize{[](KThread* thread) {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
return thread;
}};
tls_data.raw_thread.emplace(system.Kernel());
tls_data.thread = existing_thread ? existing_thread : initialize(&*tls_data.raw_thread);
ASSERT(tls_data.thread != nullptr);
}
return tls_data.thread;
}
/// Registers a CPU core thread by allocating a host thread ID for it
@ -407,32 +419,26 @@ struct KernelCore::Impl {
return this_id;
}
static inline thread_local bool is_phantom_mode_for_singlecore{false};
// Forces singlecore
bool IsPhantomModeForSingleCore() const {
return is_phantom_mode_for_singlecore;
return tls_data.is_phantom_mode_for_singlecore;
}
void SetIsPhantomModeForSingleCore(bool value) {
ASSERT(!is_multicore);
is_phantom_mode_for_singlecore = value;
tls_data.is_phantom_mode_for_singlecore = value;
}
bool IsShuttingDown() const {
return is_shutting_down.load(std::memory_order_relaxed);
}
static inline thread_local KThread* current_thread{nullptr};
KThread* GetCurrentEmuThread() {
if (!current_thread) {
current_thread = GetHostDummyThread(nullptr);
}
return current_thread;
auto *ct = tls_data.current_thread; // Must read to avoid uneeded %fs: reloads
return ct ? ct : (tls_data.current_thread = GetHostDummyThread(nullptr));
}
void SetCurrentEmuThread(KThread* thread) {
current_thread = thread;
tls_data.current_thread = thread;
}
void DeriveInitialMemoryLayout() {
@ -845,6 +851,8 @@ struct KernelCore::Impl {
// System context
Core::System& system;
// You must use references otherwise atexit() will be spammed everywhere :)
ThreadLocalData& tls_data;
};
KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {}

Loading…
Cancel
Save