bevy/crates/bevy_platform_support/src/thread.rs
Zachary Harrold 99289ad988
Add sleep based on spin to bevy_platform_support (#18633)
# Objective

- Fixes #18617

## Solution

- Added `thread::sleep` to `bevy_platform_support` using a spin-based
fallback.
- Fixed bug in `bevy_platform_support::time::Instant::elapsed`
(comparison was backwards)
- Switched `ScheduleRunnerPlugin` to use
`bevy_platform_support:🧵:sleep` on `std` and `no_std` platforms
(WASM + Browser excluded)

## Testing

- Ran reproduction code from @mockersf in linked issue and confirmed a
consistent 60 counts per `println!`.

---

## Notes

- I chose to add `bevy_platform_support:🧵:sleep` instead of
putting the fix in-line within `ScheduleRunnerPlugin` to keep the
separation of concerns clean. `sleep` is only used in one other location
in Bevy, `bevy_asset`, but I have decided to leave that as-is since
`bevy_asset` isn't `no_std` compatible anyway.
- The bug in `bevy_platform_support::time::Instant::elapsed` wasn't the
cause of this issue, but it did prevent this fix from working so I have
included the it in this PR.
2025-03-31 23:21:49 +00:00

30 lines
799 B
Rust

//! Provides `sleep` for all platforms.
pub use thread::sleep;
cfg_if::cfg_if! {
// TODO: use browser timeouts based on ScheduleRunnerPlugin::build
if #[cfg(feature = "std")] {
use std::thread;
} else {
mod fallback {
use core::{hint::spin_loop, time::Duration};
use crate::time::Instant;
/// Puts the current thread to sleep for at least the specified amount of time.
///
/// As this is a `no_std` fallback implementation, this will spin the current thread.
pub fn sleep(dur: Duration) {
let start = Instant::now();
while start.elapsed() < dur {
spin_loop()
}
}
}
use fallback as thread;
}
}