[*] 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()
|
||||
{
|
||||
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);
|
||||
this->pParent->Set();
|
||||
this->pParent = nullptr;
|
||||
pThat->Set();
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,16 +30,12 @@ namespace Aurora::IO::Loop
|
||||
reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)),
|
||||
maxIterationsOrZero_(maxIterationsOrZero)
|
||||
{
|
||||
this->targetTime_ = AuTime::CurrentClockNS();
|
||||
this->targetTime_ = AuTime::SteadyClockNS();
|
||||
}
|
||||
|
||||
LSTimerIP::~LSTimerIP()
|
||||
{
|
||||
if (this->pDispatcher)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||
this->pDispatcher->pParent = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LSTimerIP::UpdateTimeWall(AuUInt64 absTimeMs)
|
||||
@ -82,35 +79,17 @@ namespace Aurora::IO::Loop
|
||||
AU_DEBUG_MEMCRUNCH;
|
||||
AU_LOCK_GUARD(this->cs);
|
||||
|
||||
AuSPtr<LSTimerIPDispatcher> pNext;
|
||||
|
||||
if (this->pDispatcher)
|
||||
{
|
||||
AU_LOCK_GUARD(this->dispatcherMutex);
|
||||
|
||||
if (this->pDispatcher)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||
|
||||
if (this->pDispatcher->pParent)
|
||||
{
|
||||
// abort
|
||||
this->pDispatcher->pParent = nullptr;
|
||||
pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
||||
}
|
||||
else
|
||||
{
|
||||
pNext = this->pDispatcher;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
||||
}
|
||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||
AuResetMember(this->pDispatcher->pParent);
|
||||
}
|
||||
|
||||
// TODO: optimization was removed. readd it.
|
||||
auto pNext = this->pDispatcher = AuMakeShared<LSTimerIPDispatcher>();
|
||||
SysAssert(pNext, "impossible OOM during timer op");
|
||||
|
||||
pNext->pParent = this;
|
||||
pNext->pParent = this->SharedFromThis();;
|
||||
AuAsync::Schedule(absTimeNs, nullptr, {}, pNext);
|
||||
this->targetTime_ = absTimeNs;
|
||||
}
|
||||
@ -119,11 +98,10 @@ namespace Aurora::IO::Loop
|
||||
{
|
||||
AU_LOCK_GUARD(this->cs);
|
||||
|
||||
AU_LOCK_GUARD(this->dispatcherMutex);
|
||||
if (this->pDispatcher)
|
||||
{
|
||||
AU_LOCK_GUARD(this->pDispatcher->mutex);
|
||||
this->pDispatcher->pParent = nullptr;
|
||||
AuResetMember(this->pDispatcher->pParent);
|
||||
this->pDispatcher = nullptr;
|
||||
}
|
||||
}
|
||||
@ -168,17 +146,8 @@ namespace Aurora::IO::Loop
|
||||
|
||||
bool LSTimerIP::OnTrigger(AuUInt handle)
|
||||
{
|
||||
AU_LOCK_GUARD(this->cs);
|
||||
|
||||
if (IsSignaledNoSpinIfUserland())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LSEvent::Reset();
|
||||
return false;
|
||||
}
|
||||
return IsSignaledNoSpinIfUserland();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LSTimerIP::TryTakeWaitNS(AuUInt64 uTimeoutAbs)
|
||||
@ -194,13 +163,19 @@ namespace Aurora::IO::Loop
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uNextTime = AuAtomicLoad(&this->targetTime_);
|
||||
}
|
||||
|
||||
auto uNow = AuTime::CurrentClockNS();
|
||||
auto uNow = AuTime::SteadyClockNS();
|
||||
if (uNow >= uNextTime)
|
||||
{
|
||||
return this->IsSignaledNonblocking();
|
||||
}
|
||||
|
||||
// TODO: this added mess isn't even hit.
|
||||
|
||||
// Win32 note: there is quite a bit of hackery behind SleepNs
|
||||
// Win 7 and lower may spin for a bit
|
||||
// Various CPUs may enter a user-space montior condition
|
||||
@ -208,14 +183,42 @@ namespace Aurora::IO::Loop
|
||||
// Alderlake et al can tpause
|
||||
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();
|
||||
}
|
||||
else
|
||||
{
|
||||
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()
|
||||
@ -225,7 +228,7 @@ namespace Aurora::IO::Loop
|
||||
|
||||
bool LSTimerIP::TryInit()
|
||||
{
|
||||
return LSEvent::TryInit(false, false, true);
|
||||
return LSEvent::TryInit(false, true, true);
|
||||
}
|
||||
|
||||
bool LSTimerIP::IsSignaled()
|
||||
|
@ -7,6 +7,7 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include <Source/Async/IAsyncRunnable.hpp>
|
||||
#include "LSHandle.hpp"
|
||||
#include "LSEvent.hpp"
|
||||
|
||||
@ -16,13 +17,13 @@ namespace Aurora::IO::Loop
|
||||
|
||||
struct LSTimerIPDispatcher : AuAsync::IAsyncRunnable
|
||||
{
|
||||
AuMutex mutex;
|
||||
LSTimerIP *pParent {};
|
||||
AuCriticalSection mutex;
|
||||
AuWPtr<LSTimerIP> pParent {};
|
||||
|
||||
void RunAsync() override;
|
||||
};
|
||||
|
||||
struct LSTimerIP : LSEvent, ITimer
|
||||
struct LSTimerIP : LSEvent, ITimer, AuEnableSharedFromThis<LSTimerIP>
|
||||
{
|
||||
LSTimerIP(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot);
|
||||
~LSTimerIP();
|
||||
@ -53,15 +54,14 @@ namespace Aurora::IO::Loop
|
||||
void UpdateTimeInternal(AuUInt64 absTimeMs);
|
||||
void UpdateTimeInternalSteady(AuUInt64 absTimeMs);
|
||||
|
||||
private:
|
||||
//private:
|
||||
friend struct LSTimerIPDispatcher;
|
||||
AuUInt32 maxIterationsOrZero_ {};
|
||||
AuUInt64 reschedStepNsOrZero_ {}, targetTime_ {};
|
||||
AuUInt32 count_ {};
|
||||
bool bSingleshot {};
|
||||
AuUInt32 count_ {};
|
||||
|
||||
AuCriticalSection cs;
|
||||
AuMutex dispatcherMutex;
|
||||
AuSPtr<LSTimerIPDispatcher> pDispatcher;
|
||||
bool IsSignaledNonblocking();
|
||||
};
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "Loop.hpp"
|
||||
#include "ILoopSourceEx.hpp"
|
||||
#include "LSIOHandle.hpp"
|
||||
#include "LSTimerNoKernelScheduler.hpp"
|
||||
#include <Source/Threading/Primitives/SMTYield.hpp>
|
||||
|
||||
namespace Aurora::IO::Loop
|
||||
@ -70,6 +71,20 @@ namespace Aurora::IO::Loop
|
||||
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))
|
||||
{
|
||||
pMutex->Unlock();
|
||||
|
Loading…
Reference in New Issue
Block a user