[*] c111dee8
cont. Simplification of if (SignalSpuriously()) AddWatcher() continued
This commit is contained in:
parent
11e18d462a
commit
03623dfa48
@ -164,7 +164,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
// (NT 5-6.1) Unblocks one race condition, where another thread checks out our signal, and we return with nothing.
|
// (NT 5-6.1) Unblocks one race condition, where another thread checks out our signal, and we return with nothing.
|
||||||
// Normal execution of the blocked thread can continue, so long as we trigger the keyed event as though this thread was signaled.
|
// Normal execution of the blocked thread can continue, so long as we trigger the keyed event as though this thread was signaled.
|
||||||
// This is only relevant in an edge case of multi-waiters spinning, rapid signaling, and the IOU being hit once. Do this instead of ticketing.
|
// This is only relevant in an edge case of multi-waiters spinning, rapid signaling, and the IOU being hit once. Do this instead of ticketing.
|
||||||
this->SignalSpuriously();
|
pNtReleaseKeyedEvent(gKeyedEventHandle, (void *)&this->wlist, FALSE, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
if (!gUseNativeWaitCondvar)
|
if (!gUseNativeWaitCondvar)
|
||||||
{
|
{
|
||||||
this->SignalSpuriously();
|
pNtReleaseKeyedEvent(gKeyedEventHandle, (void *)&this->wlist, FALSE, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,43 +334,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConditionVariableNT::SignalSpuriously()
|
|
||||||
{
|
|
||||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
|
||||||
auto original = this->wlist;
|
|
||||||
auto expected = original;
|
|
||||||
expected = expected >> kShiftCountByBits;
|
|
||||||
|
|
||||||
if (expected)
|
|
||||||
{
|
|
||||||
// INTENTIONAL: Missing this->signalCount atomic increment to force another AddWaiter under successful keyedevent return
|
|
||||||
|
|
||||||
while (expected)
|
|
||||||
{
|
|
||||||
// INTENTIONAL: Removed the -1 so we dont have to rewatch the condvar, potentially missing a signal in the process
|
|
||||||
if (AuAtomicCompareExchange(&this->wlist, (expected << kShiftCountByBits) /*intentional clear*/, original) == original)
|
|
||||||
{
|
|
||||||
if (!gUseNativeWaitCondvar)
|
|
||||||
{
|
|
||||||
pNtReleaseKeyedEvent(gKeyedEventHandle, (void *)&this->wlist, FALSE, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// INTENTIONAL: Removal of modernt branch. We err on the side of caution by failing awake, then its up to the last waking
|
|
||||||
// thread up process to block again. So long as wlist represents all the waiting threads, it doesn't matter,
|
|
||||||
// we will continue to be signalable withouts signal being lost or any thread blocking.
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
original = this->wlist;
|
|
||||||
expected = original >> kShiftCountByBits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
::WakeConditionVariable(&this->winCond_);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConditionVariableNT::Signal()
|
void ConditionVariableNT::Signal()
|
||||||
{
|
{
|
||||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||||
|
@ -19,7 +19,6 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 timeout, bool bSpin = true);
|
bool WaitForSignalNsEx(Win32ConditionMutex *pMutex, AuUInt64 timeout, bool bSpin = true);
|
||||||
void Signal();
|
void Signal();
|
||||||
auline void SignalSpuriously();
|
|
||||||
void Broadcast();
|
void Broadcast();
|
||||||
void BroadcastN(AuUInt32 nBroadcast);
|
void BroadcastN(AuUInt32 nBroadcast);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user