OS: Optimize thread timeout checking

This commit is contained in:
Tony Wasserka 2024-03-10 11:37:26 +01:00
parent b094815ecb
commit 7d2c663901
2 changed files with 15 additions and 6 deletions

View file

@ -2290,6 +2290,7 @@ SVCEmptyFuture OS::SVCSleepThread(Thread& source, int64_t duration) {
source.status = Thread::Status::WaitingForTimeout;
ready_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
// priority_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
waiting_queue.push_back(source.GetPointer());
return MakeFuture(nullptr);
}
@ -2737,6 +2738,9 @@ break;
source.status = Thread::Status::WaitingForArbitration;
ready_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
// priority_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
if (source.timeout_at != -1) {
waiting_queue.push_back(source.GetPointer());
}
Reschedule(source.GetPointer());
}
@ -2946,6 +2950,9 @@ SVCFuture<PromisedResult,PromisedWakeIndex> OS::SVCWaitSynchronizationN(Thread&
source.status = Thread::Status::Sleeping;
ready_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
// priority_queue.remove_if([ptr=source.GetPointer()](auto elem) { return elem.lock() == ptr; });
if (source.timeout_at != -1) {
waiting_queue.push_back(source.GetPointer());
}
source.GetLogger()->info("{}Putting thread into sleep state...", ThreadPrinter{source});
Reschedule(source.GetPointer());
} else {
@ -5779,12 +5786,9 @@ void OS::ElapseTime(std::chrono::nanoseconds time) {
}*/
// TODO NOW: This should also be checked for threads waiting for arbitration or events with timeout!!!
for (auto thread_weak : threads) {
// TODO: This looks really expensive... Should just keep a list of threads waiting for timeout
auto thread = thread_weak.lock();
if (thread &&
(thread->status == Thread::Status::WaitingForTimeout || thread->status == Thread::Status::Sleeping) &&
thread->timeout_at != -1 && thread->timeout_at <= GetTimeInNanoSeconds()) {
for (auto thread_it = waiting_queue.begin(); thread_it != waiting_queue.end();) {
auto thread = thread_it->lock();
if (thread->timeout_at <= GetTimeInNanoSeconds()) {
thread->GetLogger()->info("{}Waking up thread after timeout", ThreadPrinter{*thread});
// status==Sleeping corresponds to WaitSynchronizationN timing out... TODO: This is extremely ugly, clean this up instead :/
@ -5801,6 +5805,9 @@ void OS::ElapseTime(std::chrono::nanoseconds time) {
thread->status = Thread::Status::Ready;
ready_queue.push_back(thread);
// priority_queue.push_back(thread);
thread_it = waiting_queue.erase(thread_it);
} else {
++thread_it;
}
}
}
@ -6002,6 +6009,7 @@ void OS::StartScheduler(boost::coroutines::symmetric_coroutine<void>::yield_type
if (next_thread->status == Thread::Status::WaitingForTimeout &&
next_thread->timeout_at <= GetTimeInNanoSeconds()) {
next_thread->status = Thread::Status::Ready;
waiting_queue.erase(std::remove_if(waiting_queue.begin(), waiting_queue.end(), [&next_thread](auto& elem) { return elem.lock() == next_thread; }));
}
if (next_thread->status == Thread::Status::Ready) {

View file

@ -1550,6 +1550,7 @@ public: // TODO: Ugh.
public: // TODO: privatize this again!
std::list<std::weak_ptr<Thread>> ready_queue; // Queue of threads that are ready to run
// std::list<std::weak_ptr<Thread>> priority_queue; // Queue of threads that are ready to run and should be prioritized over those in ready_queue (e.g. because they had been waiting on an event that was just signalled)
std::vector<std::weak_ptr<Thread>> waiting_queue; // List of threads waiting on a timeout
std::shared_ptr<MemoryBlockOwner> internal_memory_owner;