[*] Improve LSLocalSemaphore
This commit is contained in:
parent
a1a2d482d7
commit
3d01d6cc8f
@ -11,8 +11,6 @@
|
||||
|
||||
namespace Aurora::IO::Loop
|
||||
{
|
||||
static auto const kFutexBitWake = 256u;
|
||||
|
||||
LSLocalSemaphore::LSLocalSemaphore()
|
||||
{
|
||||
|
||||
@ -31,47 +29,58 @@ namespace Aurora::IO::Loop
|
||||
}
|
||||
|
||||
this->uAtomicSemaphore = initialCount;
|
||||
this->uAtomicWord = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
AuAtomicAdd(&this->uAtomicSemaphore, 1u);
|
||||
auto uNext = AuAtomicAdd(&this->uAtomicSemaphore, 1u);
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto uState = AuAtomicLoad(&this->uAtomicWord);
|
||||
|
||||
if (uState & kFutexBitWake)
|
||||
{
|
||||
if (AuAtomicCompareExchange(&this->uAtomicWord, uState, uState) == uState)
|
||||
if (AuAtomicLoad(&this->uAtomicWord) >= uNext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (AuAtomicCompareExchange(&this->uAtomicWord, uState + kFutexBitWake, uState) == uState)
|
||||
{
|
||||
AuAtomicAdd(&this->uAtomicWord, 1u);
|
||||
LSSemaphore::AddOne();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LSLocalSemaphore::IsSignaled()
|
||||
{
|
||||
@ -154,6 +163,29 @@ namespace Aurora::IO::Loop
|
||||
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)
|
||||
{
|
||||
auto pMutex = AuMakeShared<LSLocalSemaphore>();
|
||||
|
@ -31,7 +31,10 @@ namespace Aurora::IO::Loop
|
||||
bool TryTake();
|
||||
bool TryTakeWaitMS(AuUInt32 timeout);
|
||||
|
||||
AuAUInt32 uAtomicWord {};
|
||||
void OnPresleep() override;
|
||||
void OnFinishSleep() override;
|
||||
|
||||
AuAUInt32 uAtomicSemaphore {};
|
||||
AuAUInt32 uAtomicWord {};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user