Created
January 6, 2015 19:32
-
-
Save Subv/ee7756fcd8d701a65a9b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp | |
index ea89d6e..3026822 100644 | |
--- a/src/core/arm/dyncom/arm_dyncom.cpp | |
+++ b/src/core/arm/dyncom/arm_dyncom.cpp | |
@@ -10,6 +10,8 @@ | |
#include "core/arm/dyncom/arm_dyncom_interpreter.h" | |
#include "core/core_timing.h" | |
+#include "core/hle/kernel/thread.h" | |
+#include "core/hle/hle.h" | |
const static cpu_config_t s_arm11_cpu_info = { | |
"armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE | |
@@ -85,6 +87,14 @@ void ARM_DynCom::AddTicks(u64 ticks) { | |
} | |
void ARM_DynCom::ExecuteInstructions(int num_instructions) { | |
+ if (Kernel::IsIdleThread(Kernel::GetCurrentThreadHandle())) { | |
+ LOG_CRITICAL(Common, "Idling"); | |
+ CoreTiming::Idle(); | |
+ CoreTiming::Advance(); | |
+ HLE::Reschedule(__func__); | |
+ return; | |
+ } | |
+ | |
state->NumInstrsToExecute = num_instructions; | |
// Dyncom only breaks on instruction dispatch. This only happens on every instruction when | |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp | |
index 084fd03..8d6204d 100644 | |
--- a/src/core/hle/kernel/kernel.cpp | |
+++ b/src/core/hle/kernel/kernel.cpp | |
@@ -127,6 +127,8 @@ bool LoadExec(u32 entry_point) { | |
// 0x30 is the typical main thread priority I've seen used so far | |
g_main_thread = Kernel::SetupMainThread(0x30); | |
+ Kernel::SetupIdleThread(); | |
+ | |
return true; | |
} | |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp | |
index 872df2d..8775547 100644 | |
--- a/src/core/hle/kernel/thread.cpp | |
+++ b/src/core/hle/kernel/thread.cpp | |
@@ -11,6 +11,7 @@ | |
#include "common/thread_queue_list.h" | |
#include "core/core.h" | |
+#include "core/core_timing.h" | |
#include "core/hle/hle.h" | |
#include "core/hle/kernel/kernel.h" | |
#include "core/hle/kernel/thread.h" | |
@@ -34,6 +35,7 @@ public: | |
inline bool IsReady() const { return (status & THREADSTATUS_READY) != 0; } | |
inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; } | |
inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } | |
+ inline bool IsIdle() const { return idle; } | |
ResultVal<bool> WaitSynchronization() override { | |
const bool wait = status != THREADSTATUS_DORMANT; | |
@@ -69,6 +71,8 @@ public: | |
std::vector<Handle> waiting_threads; | |
std::string name; | |
+ | |
+ bool idle; | |
}; | |
// Lists all thread ids that aren't deleted/etc. | |
@@ -358,6 +362,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio | |
thread->wait_handle = 0; | |
thread->wait_address = 0; | |
thread->name = name; | |
+ thread->idle = false; | |
return thread; | |
} | |
@@ -444,7 +449,14 @@ ResultCode SetThreadPriority(Handle handle, s32 priority) { | |
return RESULT_SUCCESS; | |
} | |
-/// Sets up the primary application thread | |
+Handle SetupIdleThread() { | |
+ Handle handle; | |
+ Thread* thread = CreateThread(handle, "idle", 0, THREADPRIO_LOWEST, THREADPROCESSORID_0, 0, 0); | |
+ thread->idle = true; | |
+ CallThread(thread); | |
+ return handle; | |
+} | |
+ | |
Handle SetupMainThread(s32 priority, int stack_size) { | |
Handle handle; | |
@@ -468,7 +480,6 @@ Handle SetupMainThread(s32 priority, int stack_size) { | |
return handle; | |
} | |
- | |
/// Reschedules to the next available thread (call after current thread is suspended) | |
void Reschedule() { | |
Thread* prev = GetCurrentThread(); | |
@@ -517,4 +528,11 @@ void ThreadingInit() { | |
void ThreadingShutdown() { | |
} | |
+bool IsIdleThread(Handle handle) { | |
+ Thread* thread = g_handle_table.Get<Thread>(handle); | |
+ if (!thread) | |
+ return false; | |
+ return thread->IsIdle(); | |
+} | |
+ | |
} // namespace | |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h | |
index 81736a8..1224f89 100644 | |
--- a/src/core/hle/kernel/thread.h | |
+++ b/src/core/hle/kernel/thread.h | |
@@ -55,6 +55,11 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 | |
/// Sets up the primary application thread | |
Handle SetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); | |
+/// Sets up the idle thread | |
+Handle SetupIdleThread(); | |
+ | |
+bool IsIdleThread(Handle thread); | |
+ | |
/// Reschedules to the next available thread (call after current thread is suspended) | |
void Reschedule(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment