Version
bsd_timer_reproducer v0.1.0 (/tmp/minimal_reproducer)
└── tokio v1.52.2
├── bytes v1.11.1
├── libc v0.2.186
├── mio v1.2.0
│ └── libc v0.2.186
├── parking_lot v0.12.5
│ ├── lock_api v0.4.14
│ │ └── scopeguard v1.2.0
│ └── parking_lot_core v0.9.12
│ ├── cfg-if v1.0.4
│ ├── libc v0.2.186
│ └── smallvec v1.15.1
├── pin-project-lite v0.2.17
├── signal-hook-registry v1.4.8
│ ├── errno v0.3.14
│ │ └── libc v0.2.186
│ └── libc v0.2.186
├── socket2 v0.6.3
│ └── libc v0.2.186
└── tokio-macros v2.7.0 (proc-macro)
├── proc-macro2 v1.0.106
│ └── unicode-ident v1.0.24
├── quote v1.0.45
│ └── proc-macro2 v1.0.106 (*)
└── syn v2.0.117
├── proc-macro2 v1.0.106 (*)
├── quote v1.0.45 (*)
└── unicode-ident v1.0.24
I originally reproduced this with an older version of tokio; it doesn't seem to be a recent bug.
Platform
BSD. uname -a yields OpenBSD prophecy.whynothugo.nl 7.8 GENERIC.MP#54 amd64
Description
tokio::time::sleep has an ~19ms overhead. When sleeping for short amounts of time (e.g.: in the order of 30ms), this completely breaks any logic relying on sleep.
I tried this code:
use std::time::Duration;
use tokio::time::{sleep, Instant};
#[tokio::main]
async fn main() {
let timeout = Duration::from_millis(40);
println!("Running {}ms timers.", timeout.as_millis());
for _run in 1..=10 {
let start = Instant::now();
sleep(timeout).await;
let end = Instant::now();
println!("duration: {}ms", end.duration_since(start).as_millis());
}
}
I expected to see this happen: durations of aprox 40ms.
Instead, this happened: sample output:
Running 40ms timers.
duration: 53ms
duration: 59ms
duration: 59ms
duration: 59ms
duration: 59ms
duration: 60ms
duration: 49ms
duration: 59ms
duration: 60ms
duration: 59ms
I'm reproducing this on a i7-13700K.
The overhead seems to be fixed, so a 15ms sleep will sleep 25–30ms:
Running 15ms timers.
duration: 25ms
duration: 29ms
duration: 20ms
duration: 29ms
duration: 29ms
duration: 29ms
duration: 30ms
duration: 30ms
duration: 29ms
duration: 20ms
For reference, attempting to render at 60fps would require submitting frames every 16ms. The overhead in sleep already blows 118% of that budget.
Version
I originally reproduced this with an older version of tokio; it doesn't seem to be a recent bug.
Platform
BSD.
uname -ayieldsOpenBSD prophecy.whynothugo.nl 7.8 GENERIC.MP#54 amd64Description
tokio::time::sleephas an ~19ms overhead. When sleeping for short amounts of time (e.g.: in the order of 30ms), this completely breaks any logic relying onsleep.I tried this code:
I expected to see this happen: durations of aprox 40ms.
Instead, this happened: sample output:
I'm reproducing this on a i7-13700K.
The overhead seems to be fixed, so a 15ms sleep will sleep 25–30ms:
For reference, attempting to render at 60fps would require submitting frames every 16ms. The overhead in
sleepalready blows 118% of that budget.