mirror of
https://github.com/modernuo/ModernUO
synced 2026-08-11 22:23:06 -04:00
## Summary - **Timer-aware idle sleep**: Exposes `Timer.MillisecondsUntilNextTick()` to calculate remaining ms until the next timer wheel tick (0–8ms). The game loop sleeps for that duration minus a 1ms safety margin, instead of spinning at 100% CPU. - **I/O completion wakeup**: Replaces `Thread.Sleep` with `NetState.WaitForCompletion()`, which uses platform-native completion notification (RIO `RIONotify` on Windows, `eventfd` on Linux, `kevent` timeout on macOS) to wake immediately when network data arrives during sleep. - **Always-on**: Removes the debug-only `core.enableIdleCPU` config gate. The sleep is self-regulating — under load, `MillisecondsUntilNextTick` returns 0 so no sleep occurs (zero overhead). On idle, CPU drops from ~100% to ~1%. - **CPS calculation cleanup**: Replaces the 128-element ring buffer with an EMA (exponential moving average) for `CyclesPerSecond`/`AverageCPS` — fewer allocations, no LINQ `.Average()` call each sample. - **IORingGroup 1.0.6**: Adds `WaitForCompletion(int timeoutMs)` to the `IIORingGroup` interface with platform implementations: - **Windows**: `RIONotify` arms the CQ event, `WaitForSingleObject` with timeout - **Linux**: `eventfd` registered with io_uring, `poll()` with timeout - **macOS**: `kevent()` with timeout ## Test plan - [ ] Build succeeds on all platforms (`dotnet build`) - [ ] Empty server: verify CPU usage drops from ~100% to ~1% idle - [ ] Loaded server: verify no added latency — `MillisecondsUntilNextTick` returns 0 when timers are firing, sleep is skipped - [ ] Connect a client during idle — verify connection accepted within one timer tick (~8ms) - [ ] Verify `[admin` gump shows reasonable CPS values (EMA convergence) |
||
|---|---|---|
| .. | ||
| Timer.cs | ||
| Timer.DelayCall.cs | ||
| Timer.DelayStateCall.cs | ||
| Timer.Pool.cs | ||
| Timer.TimerWheel.cs | ||
| TimerExecutionToken.cs | ||