Kernel: Move WaitObject to a separate file
Now that HandleTable doesn't directly depend on WaitObject anymore, this can be separated from the main kernel.h header.
This commit is contained in:
parent
9453223075
commit
64ecf81a3c
15 changed files with 178 additions and 135 deletions
|
@ -20,85 +20,6 @@ namespace Kernel {
|
|||
unsigned int Object::next_object_id;
|
||||
HandleTable g_handle_table;
|
||||
|
||||
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
|
||||
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
||||
if (itr == waiting_threads.end())
|
||||
waiting_threads.push_back(std::move(thread));
|
||||
}
|
||||
|
||||
void WaitObject::RemoveWaitingThread(Thread* thread) {
|
||||
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
||||
// If a thread passed multiple handles to the same object,
|
||||
// the kernel might attempt to remove the thread from the object's
|
||||
// waiting threads list multiple times.
|
||||
if (itr != waiting_threads.end())
|
||||
waiting_threads.erase(itr);
|
||||
}
|
||||
|
||||
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() {
|
||||
Thread* candidate = nullptr;
|
||||
s32 candidate_priority = THREADPRIO_LOWEST + 1;
|
||||
|
||||
for (const auto& thread : waiting_threads) {
|
||||
// The list of waiting threads must not contain threads that are not waiting to be awakened.
|
||||
ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY ||
|
||||
thread->status == THREADSTATUS_WAIT_SYNCH_ALL,
|
||||
"Inconsistent thread statuses in waiting_threads");
|
||||
|
||||
if (thread->current_priority >= candidate_priority)
|
||||
continue;
|
||||
|
||||
if (ShouldWait(thread.get()))
|
||||
continue;
|
||||
|
||||
// A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or
|
||||
// in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready.
|
||||
bool ready_to_run = true;
|
||||
if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) {
|
||||
ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(),
|
||||
[&thread](const SharedPtr<WaitObject>& object) {
|
||||
return object->ShouldWait(thread.get());
|
||||
});
|
||||
}
|
||||
|
||||
if (ready_to_run) {
|
||||
candidate = thread.get();
|
||||
candidate_priority = thread->current_priority;
|
||||
}
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
void WaitObject::WakeupAllWaitingThreads() {
|
||||
while (auto thread = GetHighestPriorityReadyThread()) {
|
||||
if (!thread->IsSleepingOnWaitAll()) {
|
||||
Acquire(thread.get());
|
||||
// Set the output index of the WaitSynchronizationN call to the index of this object.
|
||||
if (thread->wait_set_output) {
|
||||
thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(this));
|
||||
thread->wait_set_output = false;
|
||||
}
|
||||
} else {
|
||||
for (auto& object : thread->wait_objects) {
|
||||
object->Acquire(thread.get());
|
||||
}
|
||||
// Note: This case doesn't update the output index of WaitSynchronizationN.
|
||||
}
|
||||
|
||||
for (auto& object : thread->wait_objects)
|
||||
object->RemoveWaitingThread(thread.get());
|
||||
thread->wait_objects.clear();
|
||||
|
||||
thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
|
||||
thread->ResumeFromWait();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const {
|
||||
return waiting_threads;
|
||||
}
|
||||
|
||||
HandleTable::HandleTable() {
|
||||
next_generation = 1;
|
||||
Clear();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue