[*] fix old unix sync regressions

do not hold switching lock while spinning as originally written and intended
This commit is contained in:
Reece Wilson 2023-06-13 11:33:29 +01:00
parent b91ce52195
commit 17c50eff64
3 changed files with 25 additions and 6 deletions

View File

@ -63,7 +63,6 @@ namespace Aurora::Threading::Primitives
AuUInt64 uStart = AuTime::SteadyClockNS(); AuUInt64 uStart = AuTime::SteadyClockNS();
AuUInt64 uEnd = uStart + uTimeout; AuUInt64 uEnd = uStart + uTimeout;
AU_LOCK_GUARD(this->mutex_);
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle()); auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle());
struct timespec tspec; struct timespec tspec;
@ -75,6 +74,16 @@ namespace Aurora::Threading::Primitives
int ret {}; int ret {};
while (!this->TryLock()) while (!this->TryLock())
{ {
AU_LOCK_GUARD(this->mutex_);
{
auto old = this->value_;
if (old == 0 && AuAtomicCompareExchange(&this->value_, 1, old) == old)
{
return true;
}
}
if (uTimeout != 0) if (uTimeout != 0)
{ {
uStart = Time::SteadyClockNS(); uStart = Time::SteadyClockNS();
@ -118,8 +127,8 @@ namespace Aurora::Threading::Primitives
void MutexImpl::Unlock() void MutexImpl::Unlock()
{ {
AU_LOCK_GUARD(this->mutex_); AU_LOCK_GUARD(this->mutex_);
this->value_ = 0; this->value_ = 0;
auto ret = ::pthread_cond_signal(&this->pthreadCv_); auto ret = ::pthread_cond_signal(&this->pthreadCv_);
SysAssert(ret == 0, "Couldn't wake any mutex waiter"); SysAssert(ret == 0, "Couldn't wake any mutex waiter");
} }

View File

@ -162,7 +162,7 @@ namespace Aurora::Threading::Primitives
void SemaphoreImpl::Unlock() void SemaphoreImpl::Unlock()
{ {
Unlock(0); Unlock(1);
} }
AUKN_SYM ISemaphore *SemaphoreNew(int iInitialCount) AUKN_SYM ISemaphore *SemaphoreNew(int iInitialCount)

View File

@ -65,7 +65,6 @@ namespace Aurora::Threading::Primitives
AuUInt64 uStart = AuTime::SteadyClockNS(); AuUInt64 uStart = AuTime::SteadyClockNS();
AuUInt64 uEnd = uStart + uTimeout; AuUInt64 uEnd = uStart + uTimeout;
AU_LOCK_GUARD(this->mutex_);
auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle()); auto mutex = reinterpret_cast<pthread_mutex_t*>(this->mutex_.GetOSHandle());
struct timespec tspec; struct timespec tspec;
@ -76,6 +75,16 @@ namespace Aurora::Threading::Primitives
while (!this->TryLock()) while (!this->TryLock())
{ {
AU_LOCK_GUARD(this->mutex_);
{
auto old = this->value_;
if ((old != 0 && AuAtomicCompareExchange(&this->value_, old - 1, old) == old))
{
return true;
}
}
if (uTimeout != 0) if (uTimeout != 0)
{ {
uStart = Time::SteadyClockNS(); uStart = Time::SteadyClockNS();
@ -121,6 +130,7 @@ namespace Aurora::Threading::Primitives
void SemaphoreImpl::Unlock(long count) void SemaphoreImpl::Unlock(long count)
{ {
AU_LOCK_GUARD(this->mutex_);
AuAtomicAdd<AuInt32>(&this->value_, count); AuAtomicAdd<AuInt32>(&this->value_, count);
if (count == 1) if (count == 1)
{ {
@ -136,7 +146,7 @@ namespace Aurora::Threading::Primitives
void SemaphoreImpl::Unlock() void SemaphoreImpl::Unlock()
{ {
Unlock(0); Unlock(1);
} }
AUKN_SYM ISemaphore *SemaphoreNew(int iInitialCount) AUKN_SYM ISemaphore *SemaphoreNew(int iInitialCount)