[*] 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())
|
if (this->sortedWork[i].size())
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GroupWorkQueue::IsEmpty(AuWorkerId_t id)
|
bool GroupWorkQueue::IsEmpty(AuWorkerId_t id)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex);
|
AU_LOCK_GUARD(this->mutex);
|
||||||
|
|
||||||
for (AU_ITERATE_N(i, AuAsync::kEWorkPrioCount))
|
for (AU_ITERATE_N(i, AuAsync::kEWorkPrioCount))
|
||||||
{
|
{
|
||||||
for (const auto &[srcId, pA] : this->sortedWork[i])
|
for (const auto &[srcId, pA] : this->sortedWork[i])
|
||||||
{
|
{
|
||||||
if (id == srcId)
|
if (id == srcId)
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupWorkQueue::Dequeue(AuList<WorkEntry_t> &queue, int maxPopCount, AuAsync::ThreadId_t id)
|
void GroupWorkQueue::Dequeue(AuList<WorkEntry_t> &queue, int maxPopCount, AuAsync::ThreadId_t id)
|
||||||
@ -590,7 +590,6 @@ namespace Aurora::Async
|
|||||||
state->pendingWorkItems.clear();
|
state->pendingWorkItems.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Account for
|
// Account for
|
||||||
// while (AuAsync.GetCurrentPool()->runForever());
|
// while (AuAsync.GetCurrentPool()->runForever());
|
||||||
// in the top most task
|
// in the top most task
|
||||||
|
@ -70,15 +70,12 @@ namespace Aurora::Threading::Primitives
|
|||||||
LARGE_INTEGER word;
|
LARGE_INTEGER word;
|
||||||
word.QuadPart = uTargetTimeNt;
|
word.QuadPart = uTargetTimeNt;
|
||||||
|
|
||||||
// forced smp stall
|
// forced smt stall
|
||||||
// see the "hopefully nt is smart enough" comment
|
// see the "hopefully nt is smart enough" comment
|
||||||
if (!bIOU)
|
if (!bIOU)
|
||||||
{
|
{
|
||||||
bIOU = DoTryIf([=]()
|
bool b = true;
|
||||||
{
|
bIOU = CheckOut(b);
|
||||||
bool b = true;
|
|
||||||
return CheckOut(b);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bRet)
|
if (bRet)
|
||||||
@ -87,14 +84,14 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
auto uNow = this->wlist;
|
auto uNow = this->wlist;
|
||||||
auto waiting = uNow >> 2u;
|
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)
|
if (AuAtomicCompareExchange(&this->wlist, uNext, uNow) == uNow)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bRet = pNtWaitForKeyedEvent(gKeyedEventHandle, &this->wlist, 0, &word) != NTSTATUS_TIMEOUT;
|
bRet = pNtWaitForKeyedEvent(gKeyedEventHandle, &this->wlist, 0, &word) != NTSTATUS_TIMEOUT;
|
||||||
}
|
}
|
||||||
else /* unblock NtReleaseKeyedEvent after an atomic this->wlist change <-> NtReleaseKeyedEvent race condition. */
|
else /* unblock NtReleaseKeyedEvent after an atomic this->wlist change <-> NtReleaseKeyedEvent race condition. */
|
||||||
@ -162,28 +159,29 @@ namespace Aurora::Threading::Primitives
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool bIOU {};
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
auto uNow = this->wlist;
|
auto uNow = this->wlist;
|
||||||
auto waiting = uNow >> 2u;
|
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)
|
if (AuAtomicCompareExchange(&this->wlist, uNext, uNow) == uNow)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// forced smp stall
|
// forced smp stall
|
||||||
bool bIOU = DoTryIf([=]()
|
if (!bIOU)
|
||||||
{
|
{
|
||||||
bool b = true;
|
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);
|
pNtWaitForKeyedEvent(gKeyedEventHandle, &this->wlist, 0, nullptr);
|
||||||
|
|
||||||
if (bIOU || CheckOut(bRet))
|
if (bIOU || CheckOut(bRet))
|
||||||
@ -246,7 +244,19 @@ namespace Aurora::Threading::Primitives
|
|||||||
return false;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
@ -290,17 +300,20 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
while (expected && uBroadcastIterations)
|
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
|
#else
|
||||||
::WakeAllConditionVariable(&this->winCond_);
|
::WakeAllConditionVariable(&this->winCond_);
|
||||||
|
Loading…
Reference in New Issue
Block a user