|
|
|
@ -35,16 +35,16 @@ public: |
|
|
|
inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } |
|
|
|
|
|
|
|
ResultVal<bool> WaitSynchronization() override { |
|
|
|
if (status != THREADSTATUS_DORMANT) { |
|
|
|
const bool wait = status != THREADSTATUS_DORMANT; |
|
|
|
if (wait) { |
|
|
|
Handle thread = GetCurrentThreadHandle(); |
|
|
|
if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { |
|
|
|
waiting_threads.push_back(thread); |
|
|
|
} |
|
|
|
WaitCurrentThread(WAITTYPE_THREADEND, this->GetHandle()); |
|
|
|
return MakeResult<bool>(true); |
|
|
|
} else { |
|
|
|
return MakeResult<bool>(false); |
|
|
|
} |
|
|
|
|
|
|
|
return MakeResult<bool>(wait); |
|
|
|
} |
|
|
|
|
|
|
|
ThreadContext context; |
|
|
|
@ -141,14 +141,9 @@ void ChangeReadyState(Thread* t, bool ready) { |
|
|
|
} |
|
|
|
|
|
|
|
/// Verify that a thread has not been released from waiting
|
|
|
|
inline bool VerifyWait(Handle handle, WaitType type, Handle wait_handle) { |
|
|
|
Thread* thread = g_object_pool.Get<Thread>(handle); |
|
|
|
inline bool VerifyWait(const Thread* thread, WaitType type, Handle wait_handle) { |
|
|
|
_dbg_assert_(KERNEL, thread != nullptr); |
|
|
|
|
|
|
|
if (type != thread->wait_type || wait_handle != thread->wait_handle) |
|
|
|
return false; |
|
|
|
|
|
|
|
return true; |
|
|
|
return type == thread->wait_type && wait_handle == thread->wait_handle; |
|
|
|
} |
|
|
|
|
|
|
|
/// Stops the current thread
|
|
|
|
@ -158,10 +153,10 @@ ResultCode StopThread(Handle handle, const char* reason) { |
|
|
|
|
|
|
|
ChangeReadyState(thread, false); |
|
|
|
thread->status = THREADSTATUS_DORMANT; |
|
|
|
for (size_t i = 0; i < thread->waiting_threads.size(); ++i) { |
|
|
|
const Handle waiting_thread = thread->waiting_threads[i]; |
|
|
|
for (Handle waiting_handle : thread->waiting_threads) { |
|
|
|
Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle); |
|
|
|
if (VerifyWait(waiting_thread, WAITTYPE_THREADEND, handle)) { |
|
|
|
ResumeThreadFromWait(waiting_thread); |
|
|
|
ResumeThreadFromWait(waiting_handle); |
|
|
|
} |
|
|
|
} |
|
|
|
thread->waiting_threads.clear(); |
|
|
|
@ -194,13 +189,13 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { |
|
|
|
s32 priority = THREADPRIO_LOWEST; |
|
|
|
|
|
|
|
// Iterate through threads, find highest priority thread that is waiting to be arbitrated...
|
|
|
|
for (const auto& handle : thread_queue) { |
|
|
|
for (Handle handle : thread_queue) { |
|
|
|
Thread* thread = g_object_pool.Get<Thread>(handle); |
|
|
|
|
|
|
|
// TODO(bunnei): Verify arbiter address...
|
|
|
|
if (!VerifyWait(handle, WAITTYPE_ARB, arbiter)) |
|
|
|
if (!VerifyWait(thread, WAITTYPE_ARB, arbiter)) |
|
|
|
continue; |
|
|
|
|
|
|
|
Thread* thread = g_object_pool.Get<Thread>(handle); |
|
|
|
if (thread == nullptr) |
|
|
|
continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up.
|
|
|
|
if(thread->current_priority <= priority) { |
|
|
|
@ -219,10 +214,11 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) { |
|
|
|
void ArbitrateAllThreads(u32 arbiter, u32 address) { |
|
|
|
|
|
|
|
// Iterate through threads, find highest priority thread that is waiting to be arbitrated...
|
|
|
|
for (const auto& handle : thread_queue) { |
|
|
|
for (Handle handle : thread_queue) { |
|
|
|
Thread* thread = g_object_pool.Get<Thread>(handle); |
|
|
|
|
|
|
|
// TODO(bunnei): Verify arbiter address...
|
|
|
|
if (VerifyWait(handle, WAITTYPE_ARB, arbiter)) |
|
|
|
if (VerifyWait(thread, WAITTYPE_ARB, arbiter)) |
|
|
|
ResumeThreadFromWait(handle); |
|
|
|
} |
|
|
|
} |
|
|
|
|