[*] Improve LSLocalSemaphore

This commit is contained in:
Reece Wilson 2023-10-21 18:12:23 +01:00
parent a1a2d482d7
commit 3d01d6cc8f
2 changed files with 62 additions and 27 deletions

View File

@ -11,8 +11,6 @@
namespace Aurora::IO::Loop namespace Aurora::IO::Loop
{ {
static auto const kFutexBitWake = 256u;
LSLocalSemaphore::LSLocalSemaphore() LSLocalSemaphore::LSLocalSemaphore()
{ {
@ -31,47 +29,58 @@ namespace Aurora::IO::Loop
} }
this->uAtomicSemaphore = initialCount; this->uAtomicSemaphore = initialCount;
this->uAtomicWord = 1;
return true; return true;
} }
bool LSLocalSemaphore::OnTrigger(AuUInt handle) bool LSLocalSemaphore::OnTrigger(AuUInt handle)
{ {
if (AuAtomicLoad(&this->uAtomicWord) & kFutexBitWake) auto bRet = this->TryTakeNoSpin();
while (true)
{ {
AuAtomicSub(&this->uAtomicWord, kFutexBitWake); auto uOld = this->uAtomicWord;
if (uOld == 0)
{
break;
} }
return this->TryTakeNoSpin(); if (AuAtomicCompareExchange(&this->uAtomicWord, uOld - 1, uOld) == uOld)
{
auto uCount = AuAtomicLoad(&this->uAtomicSemaphore);
if (uOld - 1 == 0 &&
uCount)
{
AuAtomicAdd(&this->uAtomicWord, uCount);
for (AU_ITERATE_N(i, uCount))
{
LSSemaphore::AddOne();
}
}
break;
}
}
return bRet;
} }
bool LSLocalSemaphore::AddOne() bool LSLocalSemaphore::AddOne()
{ {
AuAtomicAdd(&this->uAtomicSemaphore, 1u); auto uNext = AuAtomicAdd(&this->uAtomicSemaphore, 1u);
while (true) if (AuAtomicLoad(&this->uAtomicWord) >= uNext)
{
auto uState = AuAtomicLoad(&this->uAtomicWord);
if (uState & kFutexBitWake)
{
if (AuAtomicCompareExchange(&this->uAtomicWord, uState, uState) == uState)
{ {
return true; return true;
} }
else
{
continue;
}
}
if (AuAtomicCompareExchange(&this->uAtomicWord, uState + kFutexBitWake, uState) == uState) AuAtomicAdd(&this->uAtomicWord, 1u);
{
LSSemaphore::AddOne(); LSSemaphore::AddOne();
return true; return true;
} }
}
}
bool LSLocalSemaphore::IsSignaled() bool LSLocalSemaphore::IsSignaled()
{ {
@ -154,6 +163,29 @@ namespace Aurora::IO::Loop
return true; return true;
} }
void LSLocalSemaphore::OnPresleep()
{
#if 0
while (auto uActiveSemaphore = AuAtomicLoad(&this->uAtomicSemaphore))
{
if (AuAtomicLoad(&this->uAtomicWord) >= uActiveSemaphore)
{
return;
}
AuAtomicAdd(&this->uAtomicWord, uActiveSemaphore);
for (AU_ITERATE_N(i, uActiveSemaphore))
{
LSSemaphore::AddOne();
}
}
#endif
}
void LSLocalSemaphore::OnFinishSleep()
{
}
AUKN_SYM AuSPtr<ILSSemaphore> NewLSSemaphore(AuUInt32 initialCount) AUKN_SYM AuSPtr<ILSSemaphore> NewLSSemaphore(AuUInt32 initialCount)
{ {
auto pMutex = AuMakeShared<LSLocalSemaphore>(); auto pMutex = AuMakeShared<LSLocalSemaphore>();

View File

@ -31,7 +31,10 @@ namespace Aurora::IO::Loop
bool TryTake(); bool TryTake();
bool TryTakeWaitMS(AuUInt32 timeout); bool TryTakeWaitMS(AuUInt32 timeout);
AuAUInt32 uAtomicWord {}; void OnPresleep() override;
void OnFinishSleep() override;
AuAUInt32 uAtomicSemaphore {}; AuAUInt32 uAtomicSemaphore {};
AuAUInt32 uAtomicWord {};
}; };
} }