[*] TODO: (Finish me) Win7 ILoopQueue doesn't seem to like the in process high perf timer io primitive so much. It works fine under Linux and WaitForMultipleObject WinXP-WinRT.
Windows 7 Perf hack
This commit is contained in:
parent
36349b4d02
commit
ff65193d0f
@ -16,11 +16,12 @@ namespace Aurora::IO::Loop
|
|||||||
void LSTimerIPDispatcher::RunAsync()
|
void LSTimerIPDispatcher::RunAsync()
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->mutex);
|
AU_LOCK_GUARD(this->mutex);
|
||||||
if (this->pParent)
|
|
||||||
|
// TODO: not as optimized
|
||||||
|
// TODO: we now just added a AuSharedFromThis requirement for no good reason
|
||||||
|
if (auto pThat = AuTryLockMemoryType(this->pParent))
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->pParent->cs);
|
pThat->Set();
|
||||||
this->pParent->Set();
|
|
||||||
this->pParent = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,16 +30,12 @@ namespace Aurora::IO::Loop
|
|||||||
reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)),
|
reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)),
|
||||||
maxIterationsOrZero_(maxIterationsOrZero)
|
maxIterationsOrZero_(maxIterationsOrZero)
|
||||||
{
|
{
|
||||||
this->targetTime_ = AuTime::CurrentClockNS();
|
this->targetTime_ = AuTime::SteadyClockNS();
|
||||||
}
|
}
|
||||||
|
|
||||||
LSTimerIP::~LSTimerIP()
|
LSTimerIP::~LSTimerIP()
|
||||||
{
|
{
|
||||||
if (this->pDispatcher)
|
|
||||||
{
|
|
||||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
|
||||||
this->pDispatcher->pParent = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LSTimerIP::UpdateTimeWall(AuUInt64 absTimeMs)
|
void LSTimerIP::UpdateTimeWall(AuUInt64 absTimeMs)
|
||||||
@ -82,35 +79,17 @@ namespace Aurora::IO::Loop
|
|||||||
AU_DEBUG_MEMCRUNCH;
|
AU_DEBUG_MEMCRUNCH;
|
||||||
AU_LOCK_GUARD(this->cs);
|
AU_LOCK_GUARD(this->cs);
|
||||||
|
|
||||||
AuSPtr<LSTimerIPDispatcher> pNext;
|
|
||||||
|
|
||||||
{
|
|
||||||
AU_LOCK_GUARD(this->dispatcherMutex);
|
|
||||||
|
|
||||||
if (this->pDispatcher)
|
if (this->pDispatcher)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||||
|
AuResetMember(this->pDispatcher->pParent);
|
||||||
if (this->pDispatcher->pParent)
|
|
||||||
{
|
|
||||||
// abort
|
|
||||||
this->pDispatcher->pParent = nullptr;
|
|
||||||
pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pNext = this->pDispatcher;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: optimization was removed. readd it.
|
||||||
|
auto pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
||||||
SysAssert(pNext, "impossible OOM during timer op");
|
SysAssert(pNext, "impossible OOM during timer op");
|
||||||
|
|
||||||
pNext->pParent = this;
|
pNext->pParent = this->SharedFromThis();;
|
||||||
AuAsync::Schedule(absTimeNs, nullptr, {}, pNext);
|
AuAsync::Schedule(absTimeNs, nullptr, {}, pNext);
|
||||||
this->targetTime_ = absTimeNs;
|
this->targetTime_ = absTimeNs;
|
||||||
}
|
}
|
||||||
@ -119,11 +98,10 @@ namespace Aurora::IO::Loop
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->cs);
|
AU_LOCK_GUARD(this->cs);
|
||||||
|
|
||||||
AU_LOCK_GUARD(this->dispatcherMutex);
|
|
||||||
if (this->pDispatcher)
|
if (this->pDispatcher)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||||
this->pDispatcher->pParent = nullptr;
|
AuResetMember(this->pDispatcher->pParent);
|
||||||
this->pDispatcher = nullptr;
|
this->pDispatcher = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,18 +146,9 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSTimerIP::OnTrigger(AuUInt handle)
|
bool LSTimerIP::OnTrigger(AuUInt handle)
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->cs);
|
return IsSignaledNoSpinIfUserland();
|
||||||
|
|
||||||
if (IsSignaledNoSpinIfUserland())
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LSEvent::Reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LSTimerIP::TryTakeWaitNS(AuUInt64 uTimeoutAbs)
|
bool LSTimerIP::TryTakeWaitNS(AuUInt64 uTimeoutAbs)
|
||||||
{
|
{
|
||||||
@ -194,13 +163,19 @@ namespace Aurora::IO::Loop
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uNextTime = AuAtomicLoad(&this->targetTime_);
|
||||||
|
}
|
||||||
|
|
||||||
auto uNow = AuTime::CurrentClockNS();
|
auto uNow = AuTime::SteadyClockNS();
|
||||||
if (uNow >= uNextTime)
|
if (uNow >= uNextTime)
|
||||||
{
|
{
|
||||||
return this->IsSignaledNonblocking();
|
return this->IsSignaledNonblocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this added mess isn't even hit.
|
||||||
|
|
||||||
// Win32 note: there is quite a bit of hackery behind SleepNs
|
// Win32 note: there is quite a bit of hackery behind SleepNs
|
||||||
// Win 7 and lower may spin for a bit
|
// Win 7 and lower may spin for a bit
|
||||||
// Various CPUs may enter a user-space montior condition
|
// Various CPUs may enter a user-space montior condition
|
||||||
@ -208,14 +183,42 @@ namespace Aurora::IO::Loop
|
|||||||
// Alderlake et al can tpause
|
// Alderlake et al can tpause
|
||||||
if (uTimeoutAbs)
|
if (uTimeoutAbs)
|
||||||
{
|
{
|
||||||
AuThreading::SleepNs(AuMin(uNextTime, uTimeoutAbs) - uNow);
|
if (uTimeoutAbs < uNextTime)
|
||||||
|
{
|
||||||
|
AuThreading::SleepNs(uTimeoutAbs - uNow);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuThreading::SleepNs(uNextTime - uNow);
|
||||||
|
|
||||||
|
while (uNextTime < AuTime::SteadyClockNS())
|
||||||
|
{
|
||||||
|
if (this->IsSignaledNonblocking())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this->IsSignaledNonblocking();
|
return this->IsSignaledNonblocking();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AuThreading::SleepNs(uNextTime - uNow);
|
AuThreading::SleepNs(uNextTime - uNow);
|
||||||
return this->IsSignaledNonblocking();
|
if (this->IsSignaledNonblocking())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (AuAtomicLoad(&this->targetTime_) < AuTime::SteadyClockNS())
|
||||||
|
{
|
||||||
|
if (this->IsSignaledNonblocking())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ELoopSource LSTimerIP::GetType()
|
ELoopSource LSTimerIP::GetType()
|
||||||
@ -225,7 +228,7 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
bool LSTimerIP::TryInit()
|
bool LSTimerIP::TryInit()
|
||||||
{
|
{
|
||||||
return LSEvent::TryInit(false, false, true);
|
return LSEvent::TryInit(false, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LSTimerIP::IsSignaled()
|
bool LSTimerIP::IsSignaled()
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
***/
|
***/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <Source/Async/IAsyncRunnable.hpp>
|
||||||
#include "LSHandle.hpp"
|
#include "LSHandle.hpp"
|
||||||
#include "LSEvent.hpp"
|
#include "LSEvent.hpp"
|
||||||
|
|
||||||
@ -16,13 +17,13 @@ namespace Aurora::IO::Loop
|
|||||||
|
|
||||||
struct LSTimerIPDispatcher : AuAsync::IAsyncRunnable
|
struct LSTimerIPDispatcher : AuAsync::IAsyncRunnable
|
||||||
{
|
{
|
||||||
AuMutex mutex;
|
AuCriticalSection mutex;
|
||||||
LSTimerIP *pParent {};
|
AuWPtr<LSTimerIP> pParent {};
|
||||||
|
|
||||||
void RunAsync() override;
|
void RunAsync() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LSTimerIP : LSEvent, ITimer
|
struct LSTimerIP : LSEvent, ITimer, AuEnableSharedFromThis<LSTimerIP>
|
||||||
{
|
{
|
||||||
LSTimerIP(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot);
|
LSTimerIP(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot);
|
||||||
~LSTimerIP();
|
~LSTimerIP();
|
||||||
@ -53,15 +54,14 @@ namespace Aurora::IO::Loop
|
|||||||
void UpdateTimeInternal(AuUInt64 absTimeMs);
|
void UpdateTimeInternal(AuUInt64 absTimeMs);
|
||||||
void UpdateTimeInternalSteady(AuUInt64 absTimeMs);
|
void UpdateTimeInternalSteady(AuUInt64 absTimeMs);
|
||||||
|
|
||||||
private:
|
//private:
|
||||||
friend struct LSTimerIPDispatcher;
|
friend struct LSTimerIPDispatcher;
|
||||||
AuUInt32 maxIterationsOrZero_ {};
|
AuUInt32 maxIterationsOrZero_ {};
|
||||||
AuUInt64 reschedStepNsOrZero_ {}, targetTime_ {};
|
AuUInt64 reschedStepNsOrZero_ {}, targetTime_ {};
|
||||||
AuUInt32 count_ {};
|
|
||||||
bool bSingleshot {};
|
bool bSingleshot {};
|
||||||
|
AuUInt32 count_ {};
|
||||||
|
|
||||||
AuCriticalSection cs;
|
AuCriticalSection cs;
|
||||||
AuMutex dispatcherMutex;
|
|
||||||
AuSPtr<LSTimerIPDispatcher> pDispatcher;
|
AuSPtr<LSTimerIPDispatcher> pDispatcher;
|
||||||
bool IsSignaledNonblocking();
|
bool IsSignaledNonblocking();
|
||||||
};
|
};
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "Loop.hpp"
|
#include "Loop.hpp"
|
||||||
#include "ILoopSourceEx.hpp"
|
#include "ILoopSourceEx.hpp"
|
||||||
#include "LSIOHandle.hpp"
|
#include "LSIOHandle.hpp"
|
||||||
|
#include "LSTimerNoKernelScheduler.hpp"
|
||||||
#include <Source/Threading/Primitives/SMTYield.hpp>
|
#include <Source/Threading/Primitives/SMTYield.hpp>
|
||||||
|
|
||||||
namespace Aurora::IO::Loop
|
namespace Aurora::IO::Loop
|
||||||
@ -70,6 +71,20 @@ namespace Aurora::IO::Loop
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto pSemaphore = AuDynamicCast<Loop::LSTimerIP>(pLoopSource))
|
||||||
|
{
|
||||||
|
// TOOD:Hack:
|
||||||
|
AU_LOCK_GUARD(pSemaphore->cs);
|
||||||
|
if (pSemaphore->maxIterationsOrZero_)
|
||||||
|
{
|
||||||
|
AuAtomicSub(&pSemaphore->count_, 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSemaphore->UpdateTimeSteadyNs(pSemaphore->targetTime_ - pSemaphore->reschedStepNsOrZero_);
|
||||||
|
pSemaphore->Set();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto pMutex = AuDynamicCast<Loop::ILSMutex>(pLoopSource))
|
if (auto pMutex = AuDynamicCast<Loop::ILSMutex>(pLoopSource))
|
||||||
{
|
{
|
||||||
pMutex->Unlock();
|
pMutex->Unlock();
|
||||||
|
Loading…
Reference in New Issue
Block a user