[*] Work on AuConditionVariable.NT some more
[*] Fix high cpu regression in 6af9940b
This commit is contained in:
parent
b60b580d62
commit
53df1ee81d
@ -360,29 +360,29 @@ namespace Aurora::Async
|
||||
{
|
||||
if (this->sortedWork[i].size())
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GroupWorkQueue::IsEmpty(AuWorkerId_t id)
|
||||
{
|
||||
AU_LOCK_GUARD(this->mutex);
|
||||
|
||||
for (AU_ITERATE_N(i, AuAsync::kEWorkPrioCount))
|
||||
{
|
||||
for (const auto &[srcId, pA] : this->sortedWork[i])
|
||||
{
|
||||
if (id == srcId)
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GroupWorkQueue::Dequeue(AuList<WorkEntry_t> &queue, int maxPopCount, AuAsync::ThreadId_t id)
|
||||
@ -590,7 +590,6 @@ namespace Aurora::Async
|
||||
state->pendingWorkItems.clear();
|
||||
}
|
||||
|
||||
|
||||
// Account for
|
||||
// while (AuAsync.GetCurrentPool()->runForever());
|
||||
// in the top most task
|
||||
|
@ -70,15 +70,12 @@ namespace Aurora::Threading::Primitives
|
||||
LARGE_INTEGER word;
|
||||
word.QuadPart = uTargetTimeNt;
|
||||
|
||||
// forced smp stall
|
||||
// forced smt stall
|
||||
// see the "hopefully nt is smart enough" comment
|
||||
if (!bIOU)
|
||||
{
|
||||
bIOU = DoTryIf([=]()
|
||||
{
|
||||
bool b = true;
|
||||
return CheckOut(b);
|
||||
});
|
||||
bool b = true;
|
||||
bIOU = CheckOut(b);
|
||||
}
|
||||
|
||||
if (bRet)
|
||||
@ -87,14 +84,14 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
auto uNow = this->wlist;
|
||||
auto waiting = uNow >> 2u;
|
||||
auto uNext = ((waiting + 1) << 2u) | 1;
|
||||
auto uNext = ((waiting + 1) << 2u) | (!bool(waiting)) | (uNow & 1);
|
||||
|
||||
if (AuAtomicCompareExchange(&this->wlist, uNext, uNow) == uNow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bRet = pNtWaitForKeyedEvent(gKeyedEventHandle, &this->wlist, 0, &word) != NTSTATUS_TIMEOUT;
|
||||
}
|
||||
else /* unblock NtReleaseKeyedEvent after an atomic this->wlist change <-> NtReleaseKeyedEvent race condition. */
|
||||
@ -162,28 +159,29 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bIOU {};
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
auto uNow = this->wlist;
|
||||
auto waiting = uNow >> 2u;
|
||||
auto uNext = ((waiting + 1) << 2u) | 1;
|
||||
auto uNext = ((waiting + 1) << 2u) | (!bool(waiting)) | (uNow & 1);
|
||||
|
||||
if (AuAtomicCompareExchange(&this->wlist, uNext, uNow) == uNow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// forced smp stall
|
||||
bool bIOU = DoTryIf([=]()
|
||||
if (!bIOU)
|
||||
{
|
||||
bool b = true;
|
||||
return CheckOut(b);
|
||||
});
|
||||
bIOU = CheckOut(b);
|
||||
}
|
||||
|
||||
// then into the kernel no matter what (hopefully nt is smart enough to have a fast path)
|
||||
// then into the kernel no matter what (hopefully nt is smart enough to have a fast path)
|
||||
pNtWaitForKeyedEvent(gKeyedEventHandle, &this->wlist, 0, nullptr);
|
||||
|
||||
if (bIOU || CheckOut(bRet))
|
||||
@ -246,7 +244,19 @@ namespace Aurora::Threading::Primitives
|
||||
return false;
|
||||
}
|
||||
|
||||
return AuAtomicCompareExchange(&this->signalCount, uSignalNow - 1, uSignalNow) == uSignalNow;
|
||||
auto uSignalNext = uSignalNow - 1;
|
||||
|
||||
if (AuAtomicCompareExchange(&this->signalCount, uSignalNext, uSignalNow) != uSignalNow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (uSignalNext == 0)
|
||||
{
|
||||
InterlockedOr((volatile LONG*)&this->wlist, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
#endif
|
||||
}
|
||||
@ -290,17 +300,20 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
while (expected && uBroadcastIterations)
|
||||
{
|
||||
if (AuAtomicCompareExchange(&this->wlist, ((expected - 1) << 2) /*intentional clear*/, original) == original)
|
||||
AuAtomicAdd(&this->signalCount, 1u);
|
||||
|
||||
while (expected && uBroadcastIterations)
|
||||
{
|
||||
AuAtomicAdd(&this->signalCount, 1u);
|
||||
if (AuAtomicCompareExchange(&this->wlist, ((expected - 1) << 2) /*intentional clear*/, original) == original)
|
||||
{
|
||||
pNtReleaseKeyedEvent(gKeyedEventHandle, &this->wlist, FALSE, nullptr);
|
||||
|
||||
pNtReleaseKeyedEvent(gKeyedEventHandle, &this->wlist, FALSE, nullptr);
|
||||
uBroadcastIterations--;
|
||||
}
|
||||
|
||||
uBroadcastIterations--;
|
||||
original = this->wlist;
|
||||
expected = original >> 2;
|
||||
}
|
||||
|
||||
original = this->wlist;
|
||||
expected = original >> 2;
|
||||
}
|
||||
#else
|
||||
::WakeAllConditionVariable(&this->winCond_);
|
||||
|
Loading…
Reference in New Issue
Block a user