Repository navigation
fix(core): sleep to the next tick boundary, not past it - #1
Conversation
Ticker computed its sleep from a delta measured before Tick() ran, so every iteration slept the full remainder of the period on top of the time the frame's work had already taken. The overshoot fed back into the next iteration's delta, making the loop oscillate between long and short frames instead of settling at the fixed rate. Measure the clock after Tick() and sleep until the next tick is due, so a frame that overruns the period falls through without sleeping.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
ChangesTicker timing
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
Ticker::TickSynccomputed its sleep from a delta measured beforeTick()ran:period - deltais the time left until the next tick boundary as of line 41, but by the time itis used the frame's work has already consumed part of that period. None of it is deducted, so
every iteration sleeps the full remainder on top of the work.
Iteration time becomes
work + (period - delta)instead ofmax(work, period), and the overshootfeeds back: a long iteration leaves a large delta next time round, so that sleep is short, so the
next iteration is quick, so the delta is small and the sleep is full again. The loop oscillates
rather than settling at the fixed rate.
Measured in TinCan
Profiler capture on a worst frame, 60 Hz (16.67 ms period):
Tick(draw, present)TickFixedx2 (updates)18.11 ms of work followed by a further 14.83 ms of sleep. The frame graph showed alternating tall
and short bars, which is the oscillation above.
Fix
Read the clock after
Tick()returns and sleep until the next tick is actually due. A frame thatoverruns the period falls through with no sleep, and the existing catch-up loop absorbs the slip.
Testing
Run under TinCan: frame pacing is visibly smoother and the alternating long/short frames are gone.
The existing ticker tests cover period arithmetic and start/stop only; none assert sleep behaviour,
so none needed changing.
Summary by CodeRabbit