Skip to content

Commit 0b0dad4

Browse files
committed
Fix for issue rust-lang#129212 for the ESP-IDF
1 parent bd7aa57 commit 0b0dad4

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

Diff for: std/src/sys/pal/unix/thread.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,32 @@ impl Thread {
267267

268268
#[cfg(target_os = "espidf")]
269269
pub fn sleep(dur: Duration) {
270-
let mut micros = dur.as_micros();
271-
unsafe {
272-
while micros > 0 {
273-
let st = if micros > u32::MAX as u128 { u32::MAX } else { micros as u32 };
270+
// ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
271+
// As per the documentation of `usleep`, it is expected to support
272+
// sleep times as big as at least up to 1 second.
273+
//
274+
// ESP-IDF does support almost up to `u32::MAX`, but due to a potential integer overflow in its
275+
// `usleep` implementation
276+
// (https://github.com/espressif/esp-idf/blob/d7ca8b94c852052e3bc33292287ef4dd62c9eeb1/components/newlib/time.c#L210),
277+
// we limit the sleep time to the maximum one that would not cause the underlying `usleep` implementation to overflow
278+
// (`portTICK_PERIOD_MS` can be anything between 1 to 1000, and is 10 by default).
279+
const MAX_MICROS: u32 = u32::MAX - 1_000_000 - 1;
280+
281+
// Add any nanoseconds smaller than a microsecond as an extra microsecond
282+
// so as to comply with the `std::thread::sleep` contract which mandates
283+
// implementations to sleep for _at least_ the provided `dur`.
284+
// We can't overflow `micros` as it is a `u128`, while `Duration` is a pair of
285+
// (`u64` secs, `u32` nanos), where the nanos are strictly smaller than 1 second
286+
// (i.e. < 1_000_000_000)
287+
let mut micros = dur.as_micros() + if dur.subsec_nanos() % 1_000 > 0 { 1 } else { 0 };
288+
289+
while micros > 0 {
290+
let st = if micros > MAX_MICROS as u128 { MAX_MICROS } else { micros as u32 };
291+
unsafe {
274292
libc::usleep(st);
275-
276-
micros -= st as u128;
277293
}
294+
295+
micros -= st as u128;
278296
}
279297
}
280298

0 commit comments

Comments
 (0)