[Kernel] Add proper WakeUpAllThreads

This commit is contained in:
wheremyfoodat 2023-05-06 00:06:31 +03:00
parent 2063e84bb1
commit de537fedfb
2 changed files with 48 additions and 36 deletions

View file

@ -35,41 +35,15 @@ bool Kernel::signalEvent(Handle handle) {
// Check if there's any thread waiting on this event
if (event->waitlist != 0) {
// Wake up every single thread in the waitlist using a bit scanning algorithm
while (event->waitlist != 0) {
const uint index = std::countr_zero(event->waitlist); // Get one of the set bits to see which thread is waiting
event->waitlist ^= (1ull << index); // Remove thread from waitlist by toggling its bit
// Get the thread we'll be signalling
Thread& t = threads[index];
switch (t.status) {
case ThreadStatus::WaitSync1:
t.status = ThreadStatus::Ready;
t.gprs[0] = SVCResult::Success; // The thread did not timeout, so write success to r0
break;
case ThreadStatus::WaitSyncAny:
t.status = ThreadStatus::Ready;
t.gprs[0] = SVCResult::Success; // The thread did not timeout, so write success to r0
// Get the index of the event in the object's waitlist, write it to r1
for (size_t i = 0; i < t.waitList.size(); i++) {
if (t.waitList[i] == handle) {
t.gprs[1] = i;
break;
}
}
break;
case ThreadStatus::WaitSyncAll:
Helpers::panic("SignalEvent: Thread on WaitSyncAll");
break;
}
}
// One-shot events get cleared once they are acquired by some thread
if (event->resetType == ResetType::OneShot)
// One-shot events get cleared once they are acquired by some thread and only wake up 1 thread at a time
if (event->resetType == ResetType::OneShot) {
int index = wakeupOneThread(event->waitlist, handle); // Wake up one thread with the highest priority
event->waitlist ^= (1ull << index); // Remove thread from waitlist
event->fired = false;
} else {
wakeupAllThreads(event->waitlist, handle);
event->waitlist = 0; // No threads waiting;
}
// We must reschedule our threads if we signalled one. Some games such as FE: Awakening rely on this
// If this does not happen, we can have phenomena such as a thread waiting up a higher priority thread,