Files
resy/V2/sleep/src/lib.rs
2017-05-02 22:30:24 +02:00

96 lines
2.6 KiB
Rust

extern crate libc;
use std::time::Duration;
#[cfg(target_os = "linux")]
fn clock_nanosleep(clk_id: libc::clockid_t,
flags: libc::c_int,
rqtp: *const libc::timespec,
rmtp: *mut libc::timespec)
-> libc::c_int {
unsafe { libc::clock_nanosleep(clk_id, flags, rqtp as *const _, rmtp as *mut _) }
}
#[cfg(target_os = "macos")]
fn nanosleep(rqtp: *const libc::timespec, rmtp: *mut libc::timespec) -> libc::c_int {
unsafe { libc::nanosleep(rqtp as *const _, rmtp as *mut _) }
}
/// Sleeps for the given duration.
///
/// Examples:
///
/// ```rust
/// extern crate sleep;
/// use std::time::Duration;
///
/// // sleep 10 ms
/// sleep::sleep(Duration::from_millis(10));
/// ```
///
/// Uses `clock_nanosleep` on linux and `nanosleep` on darwin.
pub fn sleep(duration: Duration) -> Result<Duration, libc::c_int> {
let ts = duration_to_timespec(duration);
let mut remain = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
#[cfg(target_os = "linux")]
let ret = clock_nanosleep(libc::CLOCK_MONOTONIC, 0, &ts, &mut remain);
#[cfg(target_os = "macos")]
let ret = nanosleep(&ts, &mut remain);
if ret == 0 {
Ok(timespec_to_duration(remain))
} else {
Err(ret)
}
}
fn duration_to_timespec(duration: Duration) -> libc::timespec {
libc::timespec {
tv_sec: duration.as_secs() as libc::time_t,
tv_nsec: duration.subsec_nanos() as libc::c_long,
}
}
fn timespec_to_duration(timespec: libc::timespec) -> Duration {
Duration::new(timespec.tv_sec as u64, timespec.tv_nsec as u32)
}
/// Set scheduler policy and priority for process with given pid.
///
/// If `pid` equals zero, the policy of the calling process will be set.
///
/// # Examples
///
/// ```rust
/// extern crate libc;
/// extern crate sleep;
///
/// // set *round-robin* policy (default) and priority 99 (realtime) for own process
/// sleep::set_scheduler(0, libc::SCHED_RR, 99);
/// ```
#[cfg(target_os = "linux")]
pub fn set_scheduler(pid: libc::pid_t, policy: libc::c_int, priority: libc::c_int) -> libc::c_int {
let param = libc::sched_param { sched_priority: priority };
unsafe { libc::sched_setscheduler(pid, policy, &param) }
}
/// Set scheduler *round-robin* policy (default) and priority for own process.
///
/// # Examples
///
/// ```rust
/// extern crate sleep;
///
/// // set *round-robin* policy (default) and priority 99 (realtime)
/// sleep::set_priority(99);
/// ```
#[cfg(target_os = "linux")]
pub fn set_priority(priority: i32) -> libc::c_int {
set_scheduler(0, libc::SCHED_RR, priority)
}