[*] Update WoA

This commit is contained in:
Reece Wilson 2023-12-11 18:22:38 +00:00
parent 5541c25050
commit 9527a076cf
2 changed files with 73 additions and 36 deletions

View File

@ -111,7 +111,7 @@ namespace Aurora::Threading
#if !defined(WOA_SEMAPHORE_MODE)
this->mutex.Unlock();
#endif
(void)gProcessWaitables.WaitBufferFrom(this->pAddress, this->uSize);
(void)gProcessWaitables.WaitBufferFrom(this->pAddress, this->uSize, false);
#if !defined(WOA_SEMAPHORE_MODE)
this->mutex.Lock();
#endif
@ -140,7 +140,7 @@ namespace Aurora::Threading
#if !defined(WOA_SEMAPHORE_MODE)
this->mutex.Unlock();
#endif
(void)gProcessWaitables.WaitBufferFrom(this->pAddress, this->uSize);
(void)gProcessWaitables.WaitBufferFrom(this->pAddress, this->uSize, false);
#if !defined(WOA_SEMAPHORE_MODE)
this->mutex.Lock();
#endif
@ -240,7 +240,7 @@ namespace Aurora::Threading
}
}
WaitEntry *ProcessWaitNodeContainer::WaitBufferFrom(const void *pAddress, AuUInt8 uSize)
WaitEntry *ProcessWaitNodeContainer::WaitBufferFrom(const void *pAddress, AuUInt8 uSize, bool bScheduleFirst)
{
#if defined(HACK_NO_INVALID_ACCESS_LEAK_SHARED_REF_ON_DESTROYED_THREAD)
auto pReturn = tlsWaitEntry.get();
@ -248,22 +248,46 @@ namespace Aurora::Threading
auto pReturn = &tlsWaitEntry;
#endif
pReturn->pBefore = nullptr;
pReturn->pNext = nullptr;
pReturn->pAddress = pAddress;
pReturn->uSize = uSize;
pReturn->bAlive = true;
if (bScheduleFirst /*First in, First Out*/)
{
Lock();
if (auto pLoadFromMemory = this->waitList.pHead)
if (!AuExchange(pReturn->bAlive, true))
{
pReturn->pNext = pLoadFromMemory;
pLoadFromMemory->pBefore = pReturn;
if (auto pLoadFromMemory = this->waitList.pHead)
{
pLoadFromMemory->pBefore = pReturn;
pReturn->pNext = pLoadFromMemory;
}
else
{
this->waitList.pTail = pReturn;
}
this->waitList.pHead = pReturn;
}
else
Unlock();
}
else /*Last In, First Out*/
{
Lock();
if (!pReturn->bAlive)
{
if (auto pLoadFromMemory = this->waitList.pTail)
{
pLoadFromMemory->pNext = pReturn;
pReturn->pBefore = pLoadFromMemory;
}
else
{
this->waitList.pHead = pReturn;
}
this->waitList.pTail = pReturn;
pReturn->bAlive = true;
}
this->waitList.pHead = pReturn;
Unlock();
}
@ -295,30 +319,36 @@ namespace Aurora::Threading
#endif
auto [bCont, bRemove] = callback(*pCurrentHead);
pCurrentHead->bAlive = !bRemove;
if (bRemove)
{
if (pLast)
{
pLast->pNext = pCurrentHead->pNext;
}
if (this->waitList.pHead == pCurrentHead)
{
this->waitList.pHead = pCurrentHead->pNext;
}
if (this->waitList.pTail == pCurrentHead)
{
if (auto pBefore = pCurrentHead->pBefore)
{
this->waitList.pTail = pBefore;
}
else
{
this->waitList.pTail = this->waitList.pHead;
}
}
if (pCurrentHead->pBefore)
{
pCurrentHead->pBefore->pNext = pCurrentHead->pNext;
}
if (pCurrentHead->pNext)
{
pCurrentHead->pNext->pBefore = pCurrentHead->pBefore;
}
if (this->waitList.pTail == pCurrentHead)
{
this->waitList.pTail = pCurrentHead->pBefore;
}
pCurrentHead->bAlive = false;
}
if (!bCont)
@ -352,26 +382,33 @@ namespace Aurora::Threading
{
if (pCurrentHead == pSelf)
{
if (pLast)
{
pLast->pNext = pCurrentHead->pNext;
}
if (this->waitList.pHead == pCurrentHead)
{
this->waitList.pHead = pCurrentHead->pNext;
}
if (this->waitList.pTail == pCurrentHead)
{
if (auto pBefore = pCurrentHead->pBefore)
{
this->waitList.pTail = pBefore;
}
else
{
this->waitList.pTail = this->waitList.pHead;
}
}
if (pCurrentHead->pBefore)
{
pCurrentHead->pBefore->pNext = pCurrentHead->pNext;
}
if (pCurrentHead->pNext)
{
pCurrentHead->pNext->pBefore = pCurrentHead->pBefore;
}
if (this->waitList.pTail == pCurrentHead)
{
this->waitList.pTail = pCurrentHead->pBefore;
}
pCurrentHead->bAlive = false;
break;
}
@ -401,9 +438,9 @@ namespace Aurora::Threading
#define AddressToIndex AuHashCode(pAddress) & (AuArraySize(this->list) - 1)
WaitEntry *ProcessWaitContainer::WaitBufferFrom(const void *pAddress, AuUInt8 uSize)
WaitEntry *ProcessWaitContainer::WaitBufferFrom(const void *pAddress, AuUInt8 uSize, bool bScheduleFirst)
{
return this->list[AddressToIndex].WaitBufferFrom(pAddress, uSize);
return this->list[AddressToIndex].WaitBufferFrom(pAddress, uSize, bScheduleFirst);
}
template <typename T>
@ -470,7 +507,7 @@ namespace Aurora::Threading
{
WaitState state;
SysAssertDbg(uWordSize <= 32);
auto pWaitEntry = gProcessWaitables.WaitBufferFrom(pTargetAddress, uWordSize);
auto pWaitEntry = gProcessWaitables.WaitBufferFrom(pTargetAddress, uWordSize, true);
state.compare = WaitBuffer::From(pCompareAddress, uWordSize);
if (qwNanoseconds)

View File

@ -86,7 +86,7 @@ namespace Aurora::Threading
AuUInt32 uAtomic {};
ProcessListWait waitList;
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize);
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize, bool bScheduleFirst);
template <typename T>
bool IterateWake(T callback);
@ -102,7 +102,7 @@ namespace Aurora::Threading
{
ProcessWaitNodeContainer list[kDefaultWaitPerProcess];
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize);
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize, bool bScheduleFirst = true);
template <typename T>
bool IterateWake(const void *pAddress, T callback);