From 7fc61920cce7b12cfee8129a4a1ce22a97098c1d Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 23 Oct 2018 11:57:59 -0400 Subject: [PATCH] kernel/Thread: move thread wake up table and callback handle into the manager --- src/core/hle/kernel/kernel.cpp | 1 - src/core/hle/kernel/thread.cpp | 29 +++++++++++------------------ src/core/hle/kernel/thread.h | 19 ++++++++++++++----- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 0811fa699..ca68e036a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -22,7 +22,6 @@ KernelSystem::KernelSystem(u32 system_mode) { resource_limits = std::make_unique(*this); thread_manager = std::make_unique(); - Kernel::ThreadingInit(); Kernel::TimersInit(); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 71817675d..ce035e5a6 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -13,7 +13,6 @@ #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" -#include "core/core_timing.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.h" @@ -26,9 +25,6 @@ namespace Kernel { -/// Event type for the thread wake up event -static CoreTiming::EventType* ThreadWakeupEventType = nullptr; - bool Thread::ShouldWait(Thread* thread) const { return status != ThreadStatus::Dead; } @@ -37,8 +33,6 @@ void Thread::Acquire(Thread* thread) { ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); } -static std::unordered_map wakeup_callback_table; - // Lists all thread ids that aren't deleted/etc. static std::vector> thread_list; @@ -57,8 +51,8 @@ Thread* ThreadManager::GetCurrentThread() const { void Thread::Stop() { // Cancel any outstanding wakeup events for this thread - CoreTiming::UnscheduleEvent(ThreadWakeupEventType, thread_id); - wakeup_callback_table.erase(thread_id); + CoreTiming::UnscheduleEvent(thread_manager.ThreadWakeupEventType, thread_id); + thread_manager.wakeup_callback_table.erase(thread_id); // Clean up thread from ready queue // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) @@ -162,12 +156,7 @@ void ThreadManager::ExitCurrentThread() { thread_list.end()); } -/** - * Callback that will wake up the thread it was scheduled for - * @param thread_id The ID of the thread that's been awoken - * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time - */ -static void ThreadWakeupCallback(u64 thread_id, s64 cycles_late) { +void ThreadManager::ThreadWakeupCallback(u64 thread_id, s64 cycles_late) { SharedPtr thread = wakeup_callback_table.at(thread_id); if (thread == nullptr) { LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", thread_id); @@ -196,7 +185,8 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { if (nanoseconds == -1) return; - CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), ThreadWakeupEventType, thread_id); + CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), thread_manager.ThreadWakeupEventType, + thread_id); } void Thread::ResumeFromWait() { @@ -334,7 +324,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr thread->wait_objects.clear(); thread->wait_address = 0; thread->name = std::move(name); - wakeup_callback_table[thread->thread_id] = thread.get(); + thread_manager->wakeup_callback_table[thread->thread_id] = thread.get(); thread->owner_process = &owner_process; // Find the next available TLS index, and mark it as used @@ -476,8 +466,11 @@ VAddr Thread::GetCommandBufferAddress() const { //////////////////////////////////////////////////////////////////////////////////////////////////// -void ThreadingInit() { - ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); +ThreadManager::ThreadManager() { + ThreadWakeupEventType = + CoreTiming::RegisterEvent("ThreadWakeupCallback", [this](u64 thread_id, s64 cycle_late) { + ThreadWakeupCallback(thread_id, cycle_late); + }); } void ThreadingShutdown() { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 4a9384bd8..cc229dc18 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -12,6 +12,7 @@ #include "common/common_types.h" #include "common/thread_queue_list.h" #include "core/arm/arm_interface.h" +#include "core/core_timing.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" #include "core/hle/result.h" @@ -56,6 +57,8 @@ enum class ThreadWakeupReason { class ThreadManager { public: + ThreadManager(); + /** * Creates a new thread ID * @return The new thread ID @@ -105,9 +108,20 @@ private: */ Thread* PopNextReadyThread(); + /** + * Callback that will wake up the thread it was scheduled for + * @param thread_id The ID of the thread that's been awoken + * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time + */ + void ThreadWakeupCallback(u64 thread_id, s64 cycles_late); + u32 next_thread_id = 1; SharedPtr current_thread; Common::ThreadQueueList ready_queue; + std::unordered_map wakeup_callback_table; + + /// Event type for the thread wake up event + CoreTiming::EventType* ThreadWakeupEventType = nullptr; friend class Thread; friend class KernelSystem; @@ -286,11 +300,6 @@ private: SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, SharedPtr owner_process); -/** - * Initialize threading - */ -void ThreadingInit(); - /** * Shutdown threading */