-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Instant::now() broken on emscripten target #113852
Comments
@rustbot label O-wasm |
Bisected the issue in emscripten down to commit emscripten-core/emscripten@c8857a6. To summarize the phenomenon: Instant::now() has no subsecond resolution on emscripten target. Reproducer: use std::time::Instant;
#[cfg(target_os = "emscripten")]
mod emscripten {
use std::os::raw::c_uint;
extern "C" {
pub fn emscripten_get_now() -> f64;
pub fn emscripten_sleep(ms: c_uint);
}
pub fn now() -> f64 {
unsafe { emscripten_get_now() }
}
pub fn sleep(ms: u32) {
unsafe {
emscripten_sleep(ms);
}
}
}
#[cfg(target_os = "emscripten")]
fn main() {
// last emscripten_now point in time that Instant::now has ACK’d of passing
let mut last_acknowledged = emscripten::now();
let mut denied = 0;
loop {
let now = Instant::now();
let enow = emscripten::now();
emscripten::sleep(16);
let elapsed = now.elapsed().as_millis();
// some time has passed according to `Instant`
if elapsed > 0 {
let ack_now = emscripten::now();
// time spent during sleep(16) according to emscripten
let elapsed_emscripten = ack_now - enow;
// time spent since last ack passage of time according to emscripten
let elapsed_complete = ack_now - last_acknowledged;
println!(
"Instant acknowledges that {} ms have passed, after {} denied passings of time.
The real sleep duration this time according to emscripten was {} ms.
Time passed since previous non-denied passage according to emscripten: {}",
elapsed, denied, elapsed_emscripten, elapsed_complete
);
last_acknowledged = ack_now;
denied = 0;
} else {
// Instant claims that no time has passed
denied += 1;
}
}
} Prints:
etc. |
Continues in rust-lang/libc#3306 |
When targeting
wasm32-unknown-emscripten
with emscripten versions after probably emscripten-core/emscripten@c8857a6 andASYNCIFY=1
, all async operations are extremely broken, often waking up after 0 ms or 1000 ms. This is most easily observed withemscripten_sleep
calls, but when I was running a multithreaded program withRUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals'
-pthread -s PTHREAD_POOL_SIZE=4 -s PTHREAD_POOL_SIZE_STRICT=2 ASYNCIFY=1
cargo build -Z build-std=std,panic_abort --target wasm32-unknown-emscripten
the same issue could also be observed when using
std::sync::mpsc::Receiver::try_recv
, for example.The call would take 1000 ms instead of returning immediately.
Note that emscripten-core/emscripten@c8857a6 mentions that it is only (mostly) reverting emscripten-core/emscripten#16966 , BUT I do not observe the issue before 16966 nor during the time that 16966 is active.
Reproducer: https://github.com/benjamin-sieffert/emscripten-sleep-bug
All the SDL interaction can be removed and the problem still persists.
Filed an issue with emscripten at first, but it seems that the problem cannot be reproduced in C.
So it must lie in the Rust-emscripten interaction somehow, even though I am only directly calling extern "C"
emscripten_sleep
from Rust.emscripten-core/emscripten#19872
The text was updated successfully, but these errors were encountered: