[+] More threading options
[+] AuThreading::SetSpinCountTimeout [+] AuThreading::SetThreadLocalAdditionalSpinCountTimeout
This commit is contained in:
parent
e6bf022bef
commit
8bf6bdd963
@ -338,6 +338,12 @@ namespace Aurora
|
||||
bool bPreferNt51XpCondvarsOver8 { false };
|
||||
bool bPreferNtCondvarModernWinSpin { false };
|
||||
bool bPreferNtCondvarOlderWinSpin { true };
|
||||
bool bPreferNtSemaphoreSpinTryLock { true };
|
||||
bool bPreferNtMutexSpinTryLock { true };
|
||||
bool bPreferNtCondMutexSpinTryLock { true };
|
||||
bool bPreferLinuxSemaphoreSpinTryLock { true };
|
||||
bool bPreferLinuxMutexSpinTryLock { true };
|
||||
bool bPreferLinuxCondMutexSpinTryLock { true };
|
||||
bool bPreferEmulatedWakeOnAddress { false };
|
||||
};
|
||||
|
||||
|
17
Include/Aurora/Threading/SpinTime.hpp
Normal file
17
Include/Aurora/Threading/SpinTime.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: SpinTime.hpp
|
||||
Date: 2023-08-19
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Threading
|
||||
{
|
||||
// Note: the following APIs are in powers of 2!
|
||||
|
||||
AUKN_SYM void SetSpinCountTimeout(AuUInt8 uTimeout);
|
||||
AUKN_SYM AuUInt8 GetSpinCountTimeout();
|
||||
AUKN_SYM void SetThreadLocalAdditionalSpinCountTimeout(AuUInt8 uTimeout);
|
||||
}
|
@ -24,4 +24,6 @@ namespace Aurora::Threading
|
||||
#include "LockGuard.hpp"
|
||||
#include "LockGuardTry.hpp"
|
||||
|
||||
#include "SpinTime.hpp"
|
||||
|
||||
#include "Threads/Threads.hpp"
|
@ -46,11 +46,23 @@ namespace Aurora::Threading::Primitives
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
return ::TryAcquireSRWLockExclusive(&this->lock_);
|
||||
#else
|
||||
if (gRuntimeConfig.threadingConfig.bPreferNtCondMutexSpinTryLock)
|
||||
{
|
||||
return TryLockHeavy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Win32ConditionMutex::TryLockHeavy()
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
return this->TryLockNoSpin();
|
||||
return TryLockNoSpin();
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Win32ConditionMutex::TryLockNoSpin()
|
||||
@ -68,7 +80,7 @@ namespace Aurora::Threading::Primitives
|
||||
::AcquireSRWLockExclusive(&this->lock_);
|
||||
#else
|
||||
|
||||
if (this->TryLock())
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt GetOSHandle() override;
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
auline bool TryLockHeavy();
|
||||
|
||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||
NT4Mutex lock_;
|
||||
|
@ -44,7 +44,7 @@ namespace Aurora::Threading::Primitives
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MutexImpl::TryLock()
|
||||
bool MutexImpl::TryLockHeavy()
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
@ -52,6 +52,18 @@ namespace Aurora::Threading::Primitives
|
||||
});
|
||||
}
|
||||
|
||||
bool MutexImpl::TryLock()
|
||||
{
|
||||
if (gRuntimeConfig.threadingConfig.bPreferNtMutexSpinTryLock)
|
||||
{
|
||||
return TryLockHeavy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
}
|
||||
}
|
||||
|
||||
bool MutexImpl::TryLockNoSpin()
|
||||
{
|
||||
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
||||
@ -82,7 +94,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
bool returnValue = false;
|
||||
|
||||
if (this->TryLock())
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ namespace Aurora::Threading::Primitives
|
||||
bool LockNS(AuUInt64 timeout) override;
|
||||
void Unlock() override;
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
auline bool TryLockNoSpin();
|
||||
auline bool TryLockHeavy();
|
||||
|
||||
private:
|
||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||
|
@ -35,20 +35,32 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SemaphoreImpl::TryLockNoSpin()
|
||||
{
|
||||
auto old = this->dwState_;
|
||||
return (old != 0 && AuAtomicCompareExchange(&this->dwState_, old - 1, old) == old);
|
||||
}
|
||||
|
||||
bool SemaphoreImpl::TryLock()
|
||||
bool SemaphoreImpl::TryLockHeavy()
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
|
||||
bool SemaphoreImpl::TryLock()
|
||||
{
|
||||
if (gRuntimeConfig.threadingConfig.bPreferNtSemaphoreSpinTryLock)
|
||||
{
|
||||
return TryLockHeavy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
}
|
||||
}
|
||||
|
||||
bool SemaphoreImpl::LockMS(AuUInt64 uTimeout)
|
||||
{
|
||||
@ -57,7 +69,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool SemaphoreImpl::LockNS(AuUInt64 uTimeout)
|
||||
{
|
||||
if (this->TryLock())
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace Aurora::Threading::Primitives
|
||||
void Unlock() override;
|
||||
|
||||
auline bool TryLockNoSpin();
|
||||
auline bool TryLockHeavy();
|
||||
|
||||
private:
|
||||
AuUInt32 dwState_ {};
|
||||
|
@ -8,6 +8,25 @@
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "SMTYield.hpp"
|
||||
|
||||
namespace Aurora::Threading
|
||||
{
|
||||
AUKN_SYM void SetSpinCountTimeout(AuUInt8 uTimeout)
|
||||
{
|
||||
gRuntimeConfig.threadingConfig.uSpinLoopPowerA = uTimeout;
|
||||
}
|
||||
|
||||
AUKN_SYM AuUInt8 GetSpinCountTimeout()
|
||||
{
|
||||
return gRuntimeConfig.threadingConfig.uSpinLoopPowerA;
|
||||
}
|
||||
|
||||
AUKN_SYM void SetThreadLocalAdditionalSpinCountTimeout(AuUInt8 uTimeout)
|
||||
{
|
||||
gHasThreadLocalTimeout = 1;
|
||||
tlSpinCountLocal = uTimeout;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
|
||||
|
@ -7,6 +7,12 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Threading
|
||||
{
|
||||
inline AuUInt32 gHasThreadLocalTimeout {};
|
||||
inline thread_local AuUInt8 tlSpinCountLocal { 6 };
|
||||
}
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
static auline void SMPPause()
|
||||
@ -46,6 +52,24 @@ namespace Aurora::Threading::Primitives
|
||||
}
|
||||
}
|
||||
|
||||
if (gHasThreadLocalTimeout)
|
||||
{
|
||||
auto uCount = tlSpinCountLocal;
|
||||
|
||||
int loops = (1 << uCount);
|
||||
while (loops > 0)
|
||||
{
|
||||
SMPPause();
|
||||
|
||||
loops -= 1;
|
||||
|
||||
if (callback())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return callback();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user