[*] AuAsync performance improvement: avoiding the kernel
This commit is contained in:
parent
876f4439b3
commit
560ca079a4
@ -151,12 +151,19 @@ namespace Aurora::Async
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AuAtomicLoad(&pWorker->cvSleepCount))
|
||||
{
|
||||
AU_LOCK_GUARD(pWorker->cvWorkMutex);
|
||||
}
|
||||
// Barrier:
|
||||
pWorker->cvWorkMutex->Lock();
|
||||
pWorker->cvWorkMutex->Unlock();
|
||||
|
||||
pWorker->cvVariable->Signal();
|
||||
pWorker->eventLs->Set();
|
||||
pWorker->cvVariable->Signal();
|
||||
}
|
||||
|
||||
if (AuAtomicTestAndSet(&pWorker->cvLSActive, 0u) == 0)
|
||||
{
|
||||
pWorker->eventLs->Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,13 +203,13 @@ namespace Aurora::Async
|
||||
bool ThreadPool::Poll()
|
||||
{
|
||||
AuUInt32 uCount {};
|
||||
return InternalRunOne(false, uCount);
|
||||
return InternalRunOne(GetThreadStateNoWarn(), false, uCount);
|
||||
}
|
||||
|
||||
bool ThreadPool::RunOnce()
|
||||
{
|
||||
AuUInt32 uCount {};
|
||||
return InternalRunOne(true, uCount);
|
||||
return InternalRunOne(GetThreadStateNoWarn(), true, uCount);
|
||||
}
|
||||
|
||||
bool ThreadPool::Run()
|
||||
@ -229,7 +236,7 @@ namespace Aurora::Async
|
||||
AuUInt32 uCount {};
|
||||
|
||||
// Do work (blocking)
|
||||
if (!InternalRunOne(true, uCount))
|
||||
if (!InternalRunOne(pJobRunner, true, uCount))
|
||||
{
|
||||
if (this->shutdown)
|
||||
{
|
||||
@ -242,9 +249,8 @@ namespace Aurora::Async
|
||||
return ranOnce;
|
||||
}
|
||||
|
||||
bool ThreadPool::InternalRunOne(bool block, AuUInt32 &uCount)
|
||||
bool ThreadPool::InternalRunOne(AuSPtr<ThreadState> state, bool block, AuUInt32 &uCount)
|
||||
{
|
||||
auto state = GetThreadStateNoWarn();
|
||||
if (!state)
|
||||
{
|
||||
SysPushErrorUninitialized("Not an async thread");
|
||||
@ -278,7 +284,7 @@ namespace Aurora::Async
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PollInternal(false, uCount))
|
||||
if (!PollInternal(state, false, uCount))
|
||||
{
|
||||
AuThreading::ContextYield();
|
||||
}
|
||||
@ -314,15 +320,17 @@ namespace Aurora::Async
|
||||
if ((AuBuild::kIsNtDerived && runMode == ERunMode::eEfficient) ||
|
||||
(!AuBuild::kIsNtDerived))
|
||||
{
|
||||
AuAtomicAdd(&state->cvSleepCount, 1u);
|
||||
asyncLoop->WaitAny(0);
|
||||
AuAtomicSub(&state->cvSleepCount, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
success = PollInternal(false, uCount);
|
||||
success = PollInternal(state, false, uCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = PollInternal(block, uCount);
|
||||
success = PollInternal(state, block, uCount);
|
||||
}
|
||||
} //while (success);
|
||||
|
||||
@ -410,10 +418,8 @@ namespace Aurora::Async
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: rewrite queues
|
||||
bool ThreadPool::PollInternal(bool block, AuUInt32 &uCount)
|
||||
bool ThreadPool::PollInternal(AuSPtr<ThreadState> state, bool block, AuUInt32 &uCount)
|
||||
{
|
||||
auto state = GetThreadStateNoWarn();
|
||||
if (!state)
|
||||
{
|
||||
SysPushErrorUninitialized("Not an async thread");
|
||||
@ -425,6 +431,7 @@ namespace Aurora::Async
|
||||
//state->pendingWorkItems.clear();
|
||||
|
||||
{
|
||||
AuAtomicAdd(&state->cvSleepCount, 1u);
|
||||
AU_LOCK_GUARD(state->cvWorkMutex);
|
||||
|
||||
do
|
||||
@ -470,15 +477,19 @@ namespace Aurora::Async
|
||||
(this->GetThreadState()->asyncLoop->GetSourceCount() > 1) ||
|
||||
this->GetThreadState()->asyncLoop->CommitPending())) //(this->ToKernelWorkQueue()->IsSignaledPeek()))
|
||||
{
|
||||
AuAtomicSub(&state->cvSleepCount, 1u);
|
||||
return false;
|
||||
}
|
||||
|
||||
} while (state->pendingWorkItems.empty() && block);
|
||||
}
|
||||
while (state->pendingWorkItems.empty() && block);
|
||||
|
||||
if (group->workQueue.IsEmpty(state->id))
|
||||
{
|
||||
state->eventLs->Reset();
|
||||
AuAtomicStore(&state->cvLSActive, 0u);
|
||||
}
|
||||
|
||||
AuAtomicSub(&state->cvSleepCount, 1u);
|
||||
}
|
||||
|
||||
if (state->pendingWorkItems.empty())
|
||||
@ -776,7 +787,7 @@ namespace Aurora::Async
|
||||
AuUInt32 ThreadPool::PollAndCount(bool bStrict)
|
||||
{
|
||||
AuUInt32 uCount {};
|
||||
auto bRanAtLeastOne = this->InternalRunOne(false, uCount);
|
||||
auto bRanAtLeastOne = this->InternalRunOne(this->GetThreadStateNoWarn(), false, uCount);
|
||||
return uCount ? uCount : (bStrict ? bRanAtLeastOne : 0);
|
||||
}
|
||||
|
||||
@ -788,7 +799,7 @@ namespace Aurora::Async
|
||||
do
|
||||
{
|
||||
uCount = 0;
|
||||
ranAtLeastOne |= this->InternalRunOne(false, uCount);
|
||||
ranAtLeastOne |= this->InternalRunOne(this->GetThreadStateNoWarn(), false, uCount);
|
||||
}
|
||||
while (uCount);
|
||||
|
||||
@ -1091,10 +1102,12 @@ namespace Aurora::Async
|
||||
|
||||
// !!!
|
||||
|
||||
auto pA = this->GetThreadStateNoWarn();
|
||||
|
||||
if (this->shutdown ||
|
||||
this->shuttingdown_ & 2) // fast
|
||||
{
|
||||
if (GetThreadState()->rejecting)
|
||||
if (pA->rejecting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -1107,7 +1120,7 @@ namespace Aurora::Async
|
||||
do
|
||||
{
|
||||
uCount = 0;
|
||||
ranAtLeastOne |= this->InternalRunOne(false, uCount);
|
||||
ranAtLeastOne |= this->InternalRunOne(pA, false, uCount);
|
||||
}
|
||||
while (uCount);
|
||||
|
||||
@ -1350,7 +1363,7 @@ namespace Aurora::Async
|
||||
do
|
||||
{
|
||||
uCount = 0;
|
||||
this->PollInternal(false, uCount);
|
||||
this->PollInternal(jobWorker, false, uCount);
|
||||
}
|
||||
while (uCount);
|
||||
}
|
||||
|
@ -95,8 +95,8 @@ namespace Aurora::Async
|
||||
|
||||
bool Spawn(WorkerId_t workerId, bool create);
|
||||
|
||||
bool InternalRunOne(bool block, AuUInt32 &uCount);
|
||||
bool PollInternal(bool block, AuUInt32 &uCount);
|
||||
bool InternalRunOne(AuSPtr<ThreadState>, bool block, AuUInt32 &uCount);
|
||||
bool PollInternal(AuSPtr<ThreadState>, bool block, AuUInt32 &uCount);
|
||||
|
||||
size_t GetThreadWorkersCount(ThreadGroup_t group);
|
||||
|
||||
|
@ -68,6 +68,8 @@ namespace Aurora::Async
|
||||
|
||||
AuThreadPrimitives::ConditionMutex cvWorkMutex;
|
||||
AuThreadPrimitives::ConditionVariable cvVariable;
|
||||
AuAUInt32 cvSleepCount {};
|
||||
AuAUInt32 cvLSActive {};
|
||||
AuSPtr<AuLoop::ILSEvent> eventLs;
|
||||
AuSPtr<AuLoop::ILoopSource> asyncLoopSourceShared;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user