[+] Non-mutually exclusive binary semaphore / event wait path

[+] ThreadingConfig::gPreferFutexEvent
This commit is contained in:
Reece Wilson 2023-09-10 14:50:59 +01:00
parent 48dc2e790b
commit 74dc6772b0
5 changed files with 78 additions and 35 deletions

View File

@ -379,11 +379,12 @@ namespace Aurora
AuUInt64 uAdaptiveSpinCUCnt8 : 4 { 2 };
AuUInt64 uAdaptiveSpinCUCnt16 : 4 { 4 };
AuUInt64 bPreferFutexRWLock : 1 { true };
AuUInt64 bWinXpThrough7BlazeOptimizerPower : 7 { 6 }; // dont worry about it. we dont care about old portables. lets try to make older win32 targets tweak the scheduling in our favor a bit.
AuUInt64 bWinXpThrough7BlazeOptimizerPower : 12 { 300 }; // dont worry about it. we dont care about old portables. lets try to make older win32 targets tweak the scheduling in our favor a bit.
AuUInt64 bPreferLinuxPrimitivesFutexNoSpin : 1 { false };
AuUInt64 bPreferUnixPrimitivesNoSpin : 1 { false };
AuUInt64 bAlwaysRWLockWriteBiasOnReadLock : 1 { false };
AuUInt64 bEnableRWLockWriteBiasOnReadLock : 1 { true };
AuUInt64 bPreferFutexEvent : 1 { true };
};
struct DummyConfig

View File

@ -8,6 +8,7 @@
#include <Source/RuntimeInternal.hpp>
#include "AuEvent.hpp"
#include "SMTYield.hpp"
#include "../AuWakeInternal.hpp"
namespace Aurora::Threading::Primitives
{
@ -45,6 +46,28 @@ namespace Aurora::Threading::Primitives
uEndTime = uStartTime + uTimeout;
}
if (gPreferFutexEvent)
{
while (!AtomicIsEventSetLogicNoSpinNoLock())
{
EventBits bits;
bits.state = AuAtomicLoad(&this->state_);
if (bits.bTriggered)
{
if (!InternalLTSWaitOnAddressHighRes(&this->state_, &bits.state, sizeof(bits.state), uEndTime))
{
return false;
}
}
else
{
SMPPause();
}
}
}
else
{
AU_LOCK_GUARD(this->mutex_);
while (!AtomicIsEventSetLogicNoSpinNoLock())
@ -67,6 +90,7 @@ namespace Aurora::Threading::Primitives
continue;
}
}
}
return true;
}
@ -139,17 +163,7 @@ namespace Aurora::Threading::Primitives
}
}
this->mutex_.Lock();
this->mutex_.Unlock();
if (bits.bAtomicRelease)
{
this->condition_.Signal();
}
else
{
this->condition_.Broadcast();
}
this->DoSignal(bits);
}
bool EventImpl::TrySet()
@ -176,6 +190,26 @@ namespace Aurora::Threading::Primitives
}
}
this->DoSignal(bits);
return true;
}
void EventImpl::DoSignal(const EventBits &bits)
{
if (gPreferFutexEvent)
{
if (bits.bAtomicRelease)
{
InternalLTSWakeOne(&this->state_);
}
else
{
InternalLTSWakeAll(&this->state_);
}
}
else
{
this->mutex_.Lock();
this->mutex_.Unlock();
@ -187,8 +221,7 @@ namespace Aurora::Threading::Primitives
{
this->condition_.Broadcast();
}
return true;
}
}
bool EventImpl::HasOSHandle(AuMach &mach)

View File

@ -64,6 +64,8 @@ namespace Aurora::Threading::Primitives
AuUInt8 state_;
};
void DoSignal(const EventBits &bits);
#endif
};
}

View File

@ -78,8 +78,12 @@ namespace Aurora::Threading::Primitives
{
auto uCores = AuHwInfo::GetCPUInfo().uThreads;
bool bPermitWOAInternal = IsWaitOnRecommended();
gUseFutexRWLock = ThrdCfg::gPreferFutexRWLock &&
IsWaitOnRecommended();
bPermitWOAInternal;
gPreferFutexEvent = ThrdCfg::gPreferFutexEvent &&
bPermitWOAInternal;
gSpinAdaptiveThreadCount = uCores;
@ -176,5 +180,6 @@ namespace Aurora::Threading::Primitives
ThrdCfg::gPreferUnixPrimitivesNoSpin = gRuntimeConfig.threadingConfig.bPreferUnixPrimitivesNoSpin;
ThrdCfg::gAlwaysRWLockWriteBiasOnReadLock = gRuntimeConfig.threadingConfig.bAlwaysRWLockWriteBiasOnReadLock;
ThrdCfg::gEnableRWLockWriteBiasOnReadLock = gRuntimeConfig.threadingConfig.bEnableRWLockWriteBiasOnReadLock;
ThrdCfg::gPreferFutexEvent = gRuntimeConfig.threadingConfig.bPreferFutexEvent;
}
}

View File

@ -45,6 +45,7 @@ namespace Aurora::Threading::Primitives
inline AuUInt32 gAdaptiveSpinCUCnt8 {};
inline AuUInt32 gAdaptiveSpinCUCnt16 {};
inline bool gPreferFutexRWLock {};
inline bool gPreferFutexEvent {};
inline bool gWinXpThrough7BlazeOptimizerPower {};
inline bool gPreferLinuxPrimitivesFutexNoSpin {};
inline bool gPreferUnixPrimitivesNoSpin {};
@ -57,6 +58,7 @@ namespace Aurora::Threading::Primitives
inline AuUInt32 gSpinAdaptiveThreadCount {};
inline AuUInt32 gUseFutexRWLock {};
inline AuUInt32 gPreferFutexEvent {};
void InitAdaptiveThreshold();
void InitAdaptiveThresholdFirstTime();