Merge pull request #9771 from ameerj/host-thread-id

kernel: Refactor thread_local variable usage
This commit is contained in:
liamwhite 2023-02-19 13:12:43 -05:00 committed by GitHub
commit 898c5d35a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -375,23 +375,21 @@ struct KernelCore::Impl {
application_process = process; application_process = process;
} }
static inline thread_local u32 host_thread_id = UINT32_MAX; static inline thread_local u8 host_thread_id = UINT8_MAX;
/// Gets the host thread ID for the caller, allocating a new one if this is the first time /// Sets the host thread ID for the caller.
u32 GetHostThreadId(std::size_t core_id) { u32 SetHostThreadId(std::size_t core_id) {
if (host_thread_id == UINT32_MAX) { // This should only be called during core init.
// The first four slots are reserved for CPU core threads ASSERT(host_thread_id == UINT8_MAX);
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
host_thread_id = static_cast<u32>(core_id); // 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; return host_thread_id;
} }
/// Gets the host thread ID for the caller, allocating a new one if this is the first time /// Gets the host thread ID for the caller
u32 GetHostThreadId() { u32 GetHostThreadId() const {
if (host_thread_id == UINT32_MAX) {
host_thread_id = next_host_thread_id++;
}
return host_thread_id; return host_thread_id;
} }
@ -399,23 +397,19 @@ struct KernelCore::Impl {
KThread* GetHostDummyThread(KThread* existing_thread) { KThread* GetHostDummyThread(KThread* existing_thread) {
auto initialize = [this](KThread* thread) { auto initialize = [this](KThread* thread) {
ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess());
thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); thread->SetName(fmt::format("DummyThread:{}", next_host_thread_id++));
return thread; return thread;
}; };
thread_local KThread raw_thread{system.Kernel()}; thread_local KThread raw_thread{system.Kernel()};
thread_local KThread* thread = nullptr; thread_local KThread* thread = existing_thread ? existing_thread : initialize(&raw_thread);
if (thread == nullptr) {
thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread;
}
return thread; return thread;
} }
/// Registers a CPU core thread by allocating a host thread ID for it /// Registers a CPU core thread by allocating a host thread ID for it
void RegisterCoreThread(std::size_t core_id) { void RegisterCoreThread(std::size_t core_id) {
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
const auto this_id = GetHostThreadId(core_id); const auto this_id = SetHostThreadId(core_id);
if (!is_multicore) { if (!is_multicore) {
single_core_thread_id = this_id; single_core_thread_id = this_id;
} }
@ -423,7 +417,6 @@ struct KernelCore::Impl {
/// Registers a new host thread by allocating a host thread ID for it /// Registers a new host thread by allocating a host thread ID for it
void RegisterHostThread(KThread* existing_thread) { void RegisterHostThread(KThread* existing_thread) {
[[maybe_unused]] const auto this_id = GetHostThreadId();
[[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread); [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread);
} }
@ -453,11 +446,9 @@ struct KernelCore::Impl {
static inline thread_local KThread* current_thread{nullptr}; static inline thread_local KThread* current_thread{nullptr};
KThread* GetCurrentEmuThread() { KThread* GetCurrentEmuThread() {
const auto thread_id = GetCurrentHostThreadID(); if (!current_thread) {
if (thread_id >= Core::Hardware::NUM_CPU_CORES) { current_thread = GetHostDummyThread(nullptr);
return GetHostDummyThread(nullptr);
} }
return current_thread; return current_thread;
} }
@ -1012,7 +1003,7 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
} }
Kernel::KScheduler* KernelCore::CurrentScheduler() { Kernel::KScheduler* KernelCore::CurrentScheduler() {
u32 core_id = impl->GetCurrentHostThreadID(); const u32 core_id = impl->GetCurrentHostThreadID();
if (core_id >= Core::Hardware::NUM_CPU_CORES) { if (core_id >= Core::Hardware::NUM_CPU_CORES) {
// This is expected when called from not a guest thread // This is expected when called from not a guest thread
return {}; return {};