[*] Attempt to optimize AuLoop::WaitMultipleLoopSources

This commit is contained in:
Reece Wilson 2023-12-01 11:09:18 +00:00
parent b0a7417d6f
commit 507f418b81

View File

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