Skip to content

Commit c1ec192

Browse files
committed
rust: delay: Add coarse_sleep function
Adds a safe abstraction for msleep. Signed-off-by: John Baublitz <john.m.baublitz@gmail.com>
1 parent 856eb0e commit c1ec192

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

rust/kernel/delay.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Delay functions for operations like sleeping.
4+
//!
5+
//! C header: [`include/linux/delay.h`](../../../../include/linux/delay.h)
6+
7+
use crate::bindings;
8+
use core::{cmp::min, time::Duration};
9+
10+
const MILLIS_PER_SEC: u64 = 1_000;
11+
12+
/// Sleeps safely even with waitqueue interruptions.
13+
///
14+
/// This function forwards the call to the C side `msleep` function. As a result,
15+
/// `duration` will be rounded up to the nearest millisecond if granularity less
16+
/// than a millisecond is provided. Any [`Duration`] that exceeds
17+
/// [`c_uint::MAX`][core::ffi::c_uint::MAX] in milliseconds is saturated.
18+
pub fn coarse_sleep(duration: Duration) {
19+
let milli_as_nanos = Duration::MILLISECOND.subsec_nanos();
20+
21+
// Rounds the nanosecond component of `duration` up to the nearest millisecond.
22+
let nanos_as_millis = duration.subsec_nanos().wrapping_add(milli_as_nanos - 1) / milli_as_nanos;
23+
24+
// Saturates the second component of `duration` to `c_uint::MAX`.
25+
let seconds_as_millis = min(
26+
duration.as_secs().saturating_mul(MILLIS_PER_SEC),
27+
u64::from(core::ffi::c_uint::MAX),
28+
) as core::ffi::c_uint;
29+
30+
// SAFETY: msleep is safe for all values of an `unsigned int`.
31+
unsafe { bindings::msleep(seconds_as_millis.saturating_add(nanos_as_millis)) }
32+
}

rust/kernel/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#![feature(coerce_unsized)]
2828
#![feature(dispatch_from_dyn)]
2929
#![feature(unsize)]
30+
#![feature(duration_constants)]
3031

3132
// Ensure conditional compilation based on the kernel configuration works;
3233
// otherwise we may silently break things like initcall handling.
@@ -48,6 +49,7 @@ pub mod chrdev;
4849
#[cfg(CONFIG_COMMON_CLK)]
4950
pub mod clk;
5051
pub mod cred;
52+
pub mod delay;
5153
pub mod device;
5254
pub mod driver;
5355
pub mod error;

0 commit comments

Comments
 (0)