[*] Improve LSLocalSemaphore
This commit is contained in:
parent
a1a2d482d7
commit
3d01d6cc8f
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
static auto const kFutexBitWake = 256u;
|
|
||||||
|
|
||||||
LSLocalSemaphore::LSLocalSemaphore()
|
LSLocalSemaphore::LSLocalSemaphore()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -31,46 +29,57 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 this->TryTakeNoSpin();
|
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);
|
return true;
|
||||||
|
|
||||||
if (uState & kFutexBitWake)
|
|
||||||
{
|
|
||||||
if (AuAtomicCompareExchange(&this->uAtomicWord, uState, uState) == uState)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AuAtomicCompareExchange(&this->uAtomicWord, uState + kFutexBitWake, uState) == uState)
|
|
||||||
{
|
|
||||||
LSSemaphore::AddOne();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuAtomicAdd(&this->uAtomicWord, 1u);
|
||||||
|
LSSemaphore::AddOne();
|
||||||
|
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>();
|
||||||
|
@ -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 {};
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user