aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 4729a7fe..29ea6d53 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,7 +13,7 @@
#include "common/thread_queue_list.h"
#include "core/arm/arm_interface.h"
-#include "core/arm/skyeye_common/armdefs.h"
+#include "core/arm/skyeye_common/armstate.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/hle.h"
@@ -37,6 +37,10 @@ void Thread::Acquire() {
ASSERT_MSG(!ShouldWait(), "object unavailable!");
}
+// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
+// us to simply use a pool index or similar.
+static Kernel::HandleTable wakeup_callback_handle_table;
+
// Lists all thread ids that aren't deleted/etc.
static std::vector<SharedPtr<Thread>> thread_list;
@@ -93,6 +97,8 @@ void Thread::Stop() {
// Cancel any outstanding wakeup events for this thread
CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle);
+ wakeup_callback_handle_table.Close(callback_handle);
+ callback_handle = 0;
// Clean up thread from ready queue
// This is only needed when the thread is termintated forcefully (SVC TerminateProcess)
@@ -108,6 +114,7 @@ void Thread::Stop() {
for (auto& wait_object : wait_objects) {
wait_object->RemoveWaitingThread(this);
}
+ wait_objects.clear();
Kernel::g_current_process->used_tls_slots[tls_index] = false;
@@ -210,6 +217,14 @@ static void SwitchContext(Thread* new_thread) {
new_thread->context.pc -= thumb_mode ? 2 : 4;
}
+ // Clean up the thread's wait_objects, they'll be restored if needed during
+ // the svcWaitSynchronization call
+ for (int i = 0; i < new_thread->wait_objects.size(); ++i) {
+ SharedPtr<WaitObject> object = new_thread->wait_objects[i];
+ object->RemoveWaitingThread(new_thread);
+ }
+ new_thread->wait_objects.clear();
+
ready_queue.remove(new_thread->current_priority, new_thread);
new_thread->status = THREADSTATUS_RUNNING;
@@ -268,10 +283,6 @@ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) {
thread->status = THREADSTATUS_WAIT_ARB;
}
-// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing
-// us to simply use a pool index or similar.
-static Kernel::HandleTable wakeup_callback_handle_table;
-
/**
* Callback that will wake up the thread it was scheduled for
* @param thread_handle The handle of the thread that's been awoken
@@ -503,12 +514,16 @@ void ThreadingInit() {
current_thread = nullptr;
next_thread_id = 1;
-
- thread_list.clear();
- ready_queue.clear();
}
void ThreadingShutdown() {
+ current_thread = nullptr;
+
+ for (auto& t : thread_list) {
+ t->Stop();
+ }
+ thread_list.clear();
+ ready_queue.clear();
}
} // namespace