[+] Aurora::Threading::TryWaitOnAddressEx
[*] Spin on top of Linuxs kernel spin, if in non-emu mode
This commit is contained in:
parent
3225d8cbda
commit
62e8625a11
@ -381,7 +381,7 @@ namespace Aurora
|
||||
AuUInt64 bPreferEmulatedWakeOnAddress : 1 { !AuBuild::kIsNtDerived /*everybody else requires us to hit the kernel. */ };
|
||||
#endif
|
||||
AuUInt64 bPreferWaitOnAddressAlwaysSpin : 1 { false }; // ..., if emulated! if double-spinning under higher level locks, disable me.
|
||||
AuUInt64 bPreferWaitOnAddressAlwaysSpinNative : 1 { false }; // ..., if not emulated! noting that most kernels and user-schedulers will spin for you
|
||||
AuUInt64 bPreferWaitOnAddressAlwaysSpinNative : 1 { !AuBuild::kIsNtDerived }; // ..., if not emulated! noting that most kernels and user-schedulers will spin for you
|
||||
AuUInt64 bPreferRWLockReadLockSpin : 1 { true };
|
||||
AuUInt64 bUWPNanosecondEmulationCheckFirst : 1 { false };
|
||||
AuUInt64 uUWPNanosecondEmulationMaxYields : 7 { 12 };
|
||||
|
@ -83,15 +83,21 @@ namespace Aurora::Threading::Waitables
|
||||
}
|
||||
}
|
||||
|
||||
if (this->TryChkNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
(void)TryWaitOnAddress((const void *)&this->uAtomicState, &kRef, sizeof(kRef));
|
||||
|
||||
while (!this->TryChkNoSpin())
|
||||
{
|
||||
if (TryWaitOnAddressEx((const void *)&this->uAtomicState,
|
||||
&kRef,
|
||||
sizeof(kRef),
|
||||
[&](const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
return this->TryChkNoSpin();
|
||||
}))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!WaitOnAddressSteady((const void *)&this->uAtomicState, &kRef, sizeof(kRef), uTimeoutAbsNS))
|
||||
{
|
||||
if (this->TryChkNoSpin())
|
||||
|
@ -179,19 +179,22 @@ namespace Aurora::Threading::Waitables
|
||||
|
||||
auline bool TryLock2()
|
||||
{
|
||||
static const AuUInt32 kRef { 0 };
|
||||
|
||||
if (TryLock3())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const AuUInt32 kRef { 0 };
|
||||
|
||||
if (TryWaitOnAddress((const void *)&this->uAtomicState, &kRef, sizeof(kRef)))
|
||||
return TryWaitOnAddressEx((const void *)&this->uAtomicState,
|
||||
&kRef,
|
||||
sizeof(kRef),
|
||||
[&](const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
return TryLock3();
|
||||
}
|
||||
|
||||
return false;
|
||||
return this->TryLock3();
|
||||
});
|
||||
}
|
||||
|
||||
auline bool SleepOne(AuUInt64 qwTimeout)
|
||||
|
@ -27,18 +27,22 @@ namespace Aurora::Threading::Waitables
|
||||
|
||||
inline bool TryLock() override
|
||||
{
|
||||
static const AuUInt32 kRef { 0 };
|
||||
|
||||
if (TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const AuUInt32 kRef { 0 };
|
||||
if (TryWaitOnAddress((const void *)&this->uAtomicState, &kRef, sizeof(kRef)))
|
||||
return TryWaitOnAddressEx((const void *)&this->uAtomicState,
|
||||
&kRef,
|
||||
sizeof(kRef),
|
||||
[&](const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
}
|
||||
|
||||
return false;
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
|
||||
inline bool HasOSHandle(AuMach &mach) override
|
||||
|
@ -26,21 +26,22 @@ namespace Aurora::Threading::Waitables
|
||||
|
||||
inline bool TryLock() override
|
||||
{
|
||||
static const AuUInt32 kRef { 1 };
|
||||
|
||||
if (TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const AuUInt32 kRef { 1 };
|
||||
if (TryWaitOnAddress((const void *)&this->uAtomicState, &kRef, sizeof(kRef)))
|
||||
return TryWaitOnAddressEx((const void *)&this->uAtomicState,
|
||||
&kRef,
|
||||
sizeof(kRef),
|
||||
[&](const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
if (TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
|
||||
inline bool HasOSHandle(AuMach &mach) override
|
||||
|
@ -39,6 +39,11 @@ namespace Aurora::Threading
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize);
|
||||
|
||||
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize,
|
||||
const AuFunction<bool(const void *, const void *, AuUInt8)> &check);
|
||||
|
||||
// Relative timeout variant of nanosecond resolution WoA. 0 = indefinite
|
||||
AUKN_SYM bool WaitOnAddress(const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
|
@ -903,10 +903,30 @@ namespace Aurora::Threading
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize)
|
||||
{
|
||||
auto expect = WaitBuffer::From(pCompareAddress, uWordSize);
|
||||
return Primitives::DoTryIf([&]()
|
||||
{
|
||||
return !expect.Compare(pTargetAddress);
|
||||
return !WaitBuffer::Compare(pCompareAddress, uWordSize, pTargetAddress);
|
||||
});
|
||||
}
|
||||
|
||||
AUKN_SYM bool TryWaitOnAddressEx(const void *pTargetAddress,
|
||||
const void *pCompareAddress,
|
||||
AuUInt8 uWordSize,
|
||||
const AuFunction<bool(const void *, const void *, AuUInt8)> &check)
|
||||
{
|
||||
if (!check)
|
||||
{
|
||||
return TryWaitOnAddress(pTargetAddress, pCompareAddress, uWordSize);
|
||||
}
|
||||
|
||||
return Primitives::DoTryIf([&]()
|
||||
{
|
||||
if (WaitBuffer::Compare(pCompareAddress, uWordSize, pTargetAddress))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return check(pTargetAddress, pCompareAddress, uWordSize);
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user