diff --git a/Include/Aurora/IO/Loop/Loop.hpp b/Include/Aurora/IO/Loop/Loop.hpp index 3b3e9066..74164310 100644 --- a/Include/Aurora/IO/Loop/Loop.hpp +++ b/Include/Aurora/IO/Loop/Loop.hpp @@ -52,6 +52,9 @@ namespace Aurora::IO::Loop struct ITimer : virtual ILoopSource { + /* Warning: IO timers use wall time (CurrentClock[M/NS), not SteadyClock[M/N]S()). + Use auasync timers for steady-clock timing and tick timing information. */ + virtual void UpdateTime(AuUInt64 absTimeMs) = 0; virtual void UpdateTimeNs(AuUInt64 absTimeNs) = 0; virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero = 0, AuUInt32 maxIterationsOrZero = 0) = 0; diff --git a/Source/IO/Loop/LSTimer.NT.cpp b/Source/IO/Loop/LSTimer.NT.cpp index f0cc54ec..6e7c5a6a 100644 --- a/Source/IO/Loop/LSTimer.NT.cpp +++ b/Source/IO/Loop/LSTimer.NT.cpp @@ -29,17 +29,15 @@ namespace Aurora::IO::Loop void LSTimer::UpdateTime(AuUInt64 absTimeMs) { - this->targetTime_ = AuTime::ConvertTimestamp(absTimeMs); - UpdateTimeInternal(this->targetTime_); + UpdateTimeInternalNTWall(AuTime::ConvertTimestamp(absTimeMs)); } void LSTimer::UpdateTimeNs(AuUInt64 absTimeNs) { - this->targetTime_ = AuTime::ConvertTimestampNs(absTimeNs); - UpdateTimeInternal(this->targetTime_); + UpdateTimeInternalNTWall(AuTime::ConvertTimestampNs(absTimeNs)); } - void LSTimer::UpdateTimeInternal(AuUInt64 absTimeNs) + void LSTimer::UpdateTimeInternalNTWall(AuUInt64 absTimeNs) { LARGE_INTEGER i; this->targetTime_ = absTimeNs; @@ -52,7 +50,7 @@ namespace Aurora::IO::Loop this->reschedStepNsOrZero_ = AuMSToNS(reschedStepMsOrZero); this->maxIterationsOrZero_ = maxIterationsOrZero; this->count_ = 0; - UpdateTimeInternal(this->targetTime_); + UpdateTimeInternalNTWall(this->targetTime_); } void LSTimer::UpdateTickRateIfAnyNs(AuUInt64 reschedStepNsOrZero, AuUInt32 maxIterationsOrZero) @@ -60,28 +58,35 @@ namespace Aurora::IO::Loop this->reschedStepNsOrZero_ = reschedStepNsOrZero; this->maxIterationsOrZero_ = maxIterationsOrZero; this->count_ = 0; - UpdateTimeInternal(this->targetTime_); + UpdateTimeInternalNTWall(this->targetTime_); } bool LSTimer::OnTrigger(AuUInt handle) { - SysAssert(this->targetTime_ <= AuTime::ConvertTimestampNs(AuTime::CurrentClockNS())); - if (!this->reschedStepNsOrZero_) { return true; } + auto uCurrentTime = AuTime::ConvertTimestampNs(AuTime::CurrentClockNS()); + auto uNextTick = this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL); + + if (this->targetTime_ > uCurrentTime || + uCurrentTime > uNextTick) + { + this->targetTime_ = uCurrentTime; + uNextTick = this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL); + } + if (!this->maxIterationsOrZero_) { - this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL)); + this->UpdateTimeInternalNTWall(uNextTick); return true; } - bool ok = AuAtomicAdd(&this->count_, 1) <= this->maxIterationsOrZero_; - if (ok) + if (AuAtomicAdd(&this->count_, 1) <= this->maxIterationsOrZero_) { - this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL)); + this->UpdateTimeInternalNTWall(uNextTick); return true; } else diff --git a/Source/IO/Loop/LSTimer.NT.hpp b/Source/IO/Loop/LSTimer.NT.hpp index 5f7a5575..531ec72a 100644 --- a/Source/IO/Loop/LSTimer.NT.hpp +++ b/Source/IO/Loop/LSTimer.NT.hpp @@ -27,7 +27,7 @@ namespace Aurora::IO::Loop virtual bool WaitOn(AuUInt32 timeout) override; virtual ELoopSource GetType() override; - void UpdateTimeInternal(AuUInt64 absTimeNs); + void UpdateTimeInternalNTWall(AuUInt64 absTimeNs); private: AuUInt64 reschedStepNsOrZero_ {0};