diff --git a/Source/IO/Loop/Loop.cpp b/Source/IO/Loop/Loop.cpp index e2a0930c..ed568d1d 100644 --- a/Source/IO/Loop/Loop.cpp +++ b/Source/IO/Loop/Loop.cpp @@ -8,6 +8,7 @@ #include #include "Loop.hpp" #include "ILoopSourceEx.hpp" +#include namespace Aurora::IO::Loop { @@ -92,8 +93,6 @@ namespace Aurora::IO::Loop bool bAny, AuOptionalEx uTimeoutMS) { - AU_DEBUG_MEMCRUNCH; - signaled.clear(); AuList reverseList; @@ -102,10 +101,30 @@ namespace Aurora::IO::Loop return true; } + if (lsList.size() == 1) + { + auto pSource = lsList[0]; + if (!pSource) + { + return false; + } + + if (uTimeoutMS) + { + return pSource->WaitOn(uTimeoutMS.value()); + } + else + { + return pSource->IsSignaled(); + } + } + auto uTimeoutEnd = uTimeoutMS ? AuTime::SteadyClockNS() + AuMSToNS(uTimeoutMS) : 0; + AU_DEBUG_MEMCRUNCH; + signaled.reserve(lsList.size()); if (!bAny) @@ -180,43 +199,73 @@ namespace Aurora::IO::Loop else { bool bTimedout {}; - AuList> next; AuList> signalTemp; - for (const auto &pSource : lsList) + auto lsList2 = lsList; + bool bAnyFound {}; + + auto DoTheThing = [&]() { - if (pSource->GetType() == ELoopSource::eSourceMutex || - pSource->GetType() == ELoopSource::eSourceSemaphore || - pSource->GetType() == ELoopSource::eSourceEvent) + for (auto itr = lsList2.begin(); + itr != lsList2.end(); + ) { - if (pSource->IsSignaled()) + auto pSource = *itr; + + if (pSource->GetType() == ELoopSource::eSourceMutex || + pSource->GetType() == ELoopSource::eSourceSemaphore || + pSource->GetType() == ELoopSource::eSourceEvent) { - signalTemp.push_back(pSource); + auto pSourceEx = AuDynamicCast(pSource); + + bAnyFound = true; + + if ((pSourceEx && pSourceEx->IsSignaledNoSpinIfUserland()) || + (!pSourceEx && pSource->IsSignaled())) + { + signalTemp.push_back(pSource); + itr = lsList2.erase(itr); + } + else + { + itr++; + } } else { - next.push_back(pSource); + itr++; } } - else + }; + + if (gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized) + { + AuThreadPrimitives::DoTryIf([&]() { - next.push_back(pSource); - } + DoTheThing(); + return lsList2.size() != lsList.size() || + !bAnyFound; + }); } - if (next.size()) + if (bAnyFound || !gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized) + { + DoTheThing(); + } + + if (lsList2.size()) { if (signalTemp.size()) { uTimeoutMS = 1; } #if defined(AURORA_IS_MODERNNT_DERIVED) - signaled = WaitMultipleOrObjects(next, uTimeoutMS); + signaled = WaitMultipleOrObjects(lsList2, uTimeoutMS); bTimedout = uTimeoutMS ? Time::SteadyClockNS() >= uTimeoutEnd : false; #else - signaled = WaitMultipleOrObjectsFallback(next, uTimeoutMS, bTimedout); + signaled = WaitMultipleOrObjectsFallback(lsList2, uTimeoutMS, bTimedout); #endif }