[*] 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 "Loop.hpp"
#include "ILoopSourceEx.hpp"
#include <Source/Threading/Primitives/SMTYield.hpp>
namespace Aurora::IO::Loop
{
@ -92,8 +93,6 @@ namespace Aurora::IO::Loop
bool bAny,
AuOptionalEx<AuUInt32> uTimeoutMS)
{
AU_DEBUG_MEMCRUNCH;
signaled.clear();
AuList<AuUInt32> 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<AuUInt64>(uTimeoutMS) :
0;
AU_DEBUG_MEMCRUNCH;
signaled.reserve(lsList.size());
if (!bAny)
@ -180,43 +199,73 @@ namespace Aurora::IO::Loop
else
{
bool bTimedout {};
AuList<AuSPtr<Loop::ILoopSource>> next;
AuList<AuSPtr<Loop::ILoopSource>> 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<Loop::ILoopSourceEx>(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
}