[+] 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 bPreferNt51XpCondvarsOver8 { false };
|
||||||
bool bPreferNtCondvarModernWinSpin { false };
|
bool bPreferNtCondvarModernWinSpin { false };
|
||||||
bool bPreferNtCondvarOlderWinSpin { true };
|
bool bPreferNtCondvarOlderWinSpin { true };
|
||||||
|
bool bPreferNtSemaphoreSpinTryLock { true };
|
||||||
|
bool bPreferNtMutexSpinTryLock { true };
|
||||||
|
bool bPreferNtCondMutexSpinTryLock { true };
|
||||||
|
bool bPreferLinuxSemaphoreSpinTryLock { true };
|
||||||
|
bool bPreferLinuxMutexSpinTryLock { true };
|
||||||
|
bool bPreferLinuxCondMutexSpinTryLock { true };
|
||||||
bool bPreferEmulatedWakeOnAddress { false };
|
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 "LockGuard.hpp"
|
||||||
#include "LockGuardTry.hpp"
|
#include "LockGuardTry.hpp"
|
||||||
|
|
||||||
|
#include "SpinTime.hpp"
|
||||||
|
|
||||||
#include "Threads/Threads.hpp"
|
#include "Threads/Threads.hpp"
|
@ -46,11 +46,23 @@ namespace Aurora::Threading::Primitives
|
|||||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||||
return ::TryAcquireSRWLockExclusive(&this->lock_);
|
return ::TryAcquireSRWLockExclusive(&this->lock_);
|
||||||
#else
|
#else
|
||||||
|
if (gRuntimeConfig.threadingConfig.bPreferNtCondMutexSpinTryLock)
|
||||||
|
{
|
||||||
|
return TryLockHeavy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TryLockNoSpin();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Win32ConditionMutex::TryLockHeavy()
|
||||||
|
{
|
||||||
return DoTryIf([=]()
|
return DoTryIf([=]()
|
||||||
{
|
{
|
||||||
return this->TryLockNoSpin();
|
return TryLockNoSpin();
|
||||||
});
|
});
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Win32ConditionMutex::TryLockNoSpin()
|
bool Win32ConditionMutex::TryLockNoSpin()
|
||||||
@ -68,7 +80,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
::AcquireSRWLockExclusive(&this->lock_);
|
::AcquireSRWLockExclusive(&this->lock_);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (this->TryLock())
|
if (this->TryLockHeavy())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuUInt GetOSHandle() override;
|
AuUInt GetOSHandle() override;
|
||||||
|
|
||||||
auline bool TryLockNoSpin();
|
auline bool TryLockNoSpin();
|
||||||
|
auline bool TryLockHeavy();
|
||||||
|
|
||||||
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
#if !defined(AURORA_FORCE_SRW_LOCKS)
|
||||||
NT4Mutex lock_;
|
NT4Mutex lock_;
|
||||||
|
@ -44,7 +44,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MutexImpl::TryLock()
|
bool MutexImpl::TryLockHeavy()
|
||||||
{
|
{
|
||||||
return DoTryIf([=]()
|
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()
|
bool MutexImpl::TryLockNoSpin()
|
||||||
{
|
{
|
||||||
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
return AuAtomicTestAndSet(&this->state_, 0) == 0;
|
||||||
@ -82,7 +94,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
bool returnValue = false;
|
bool returnValue = false;
|
||||||
|
|
||||||
if (this->TryLock())
|
if (this->TryLockHeavy())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,8 @@ namespace Aurora::Threading::Primitives
|
|||||||
bool LockNS(AuUInt64 timeout) override;
|
bool LockNS(AuUInt64 timeout) override;
|
||||||
void Unlock() override;
|
void Unlock() override;
|
||||||
|
|
||||||
auline bool TryLockNoSpin();
|
auline bool TryLockNoSpin();
|
||||||
|
auline bool TryLockHeavy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if defined(AURORA_FORCE_SRW_LOCKS)
|
#if defined(AURORA_FORCE_SRW_LOCKS)
|
||||||
|
@ -35,20 +35,32 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SemaphoreImpl::TryLockNoSpin()
|
bool SemaphoreImpl::TryLockNoSpin()
|
||||||
{
|
{
|
||||||
auto old = this->dwState_;
|
auto old = this->dwState_;
|
||||||
return (old != 0 && AuAtomicCompareExchange(&this->dwState_, old - 1, old) == old);
|
return (old != 0 && AuAtomicCompareExchange(&this->dwState_, old - 1, old) == old);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SemaphoreImpl::TryLock()
|
bool SemaphoreImpl::TryLockHeavy()
|
||||||
{
|
{
|
||||||
return DoTryIf([=]()
|
return DoTryIf([=]()
|
||||||
{
|
{
|
||||||
return TryLockNoSpin();
|
return TryLockNoSpin();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SemaphoreImpl::TryLock()
|
||||||
|
{
|
||||||
|
if (gRuntimeConfig.threadingConfig.bPreferNtSemaphoreSpinTryLock)
|
||||||
|
{
|
||||||
|
return TryLockHeavy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TryLockNoSpin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SemaphoreImpl::LockMS(AuUInt64 uTimeout)
|
bool SemaphoreImpl::LockMS(AuUInt64 uTimeout)
|
||||||
{
|
{
|
||||||
@ -57,7 +69,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool SemaphoreImpl::LockNS(AuUInt64 uTimeout)
|
bool SemaphoreImpl::LockNS(AuUInt64 uTimeout)
|
||||||
{
|
{
|
||||||
if (this->TryLock())
|
if (this->TryLockHeavy())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
void Unlock() override;
|
void Unlock() override;
|
||||||
|
|
||||||
auline bool TryLockNoSpin();
|
auline bool TryLockNoSpin();
|
||||||
|
auline bool TryLockHeavy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuUInt32 dwState_ {};
|
AuUInt32 dwState_ {};
|
||||||
|
@ -8,6 +8,25 @@
|
|||||||
#include <Source/RuntimeInternal.hpp>
|
#include <Source/RuntimeInternal.hpp>
|
||||||
#include "SMTYield.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
|
namespace Aurora::Threading::Primitives
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -7,6 +7,12 @@
|
|||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
namespace Aurora::Threading
|
||||||
|
{
|
||||||
|
inline AuUInt32 gHasThreadLocalTimeout {};
|
||||||
|
inline thread_local AuUInt8 tlSpinCountLocal { 6 };
|
||||||
|
}
|
||||||
|
|
||||||
namespace Aurora::Threading::Primitives
|
namespace Aurora::Threading::Primitives
|
||||||
{
|
{
|
||||||
static auline void SMPPause()
|
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();
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user