extern crate libc; use std::time::Duration; const CLOCK_MONOTONIC: i32 = 1; #[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 clock_nanosleep(_clk_id: libc::c_int, _flags: libc::c_int, 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. /// /// Uses `clock_nanosleep` on linux and `nanosleep` on darwin. pub fn sleep(duration: Duration) -> Result { let ts = duration_to_timespec(duration); let mut remain = libc::timespec { tv_sec: 0, tv_nsec: 0, }; let ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &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 /// // set *round-robin* policy (default) and priority 99 (realtime) for own process /// 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, ¶m) } } /// Set scheduler *round-robin* policy (default) and priority for own process. /// /// # Examples /// /// ```rust /// // set *round-robin* policy (default) and priority 99 (realtime) /// set_priority(99); /// ``` #[cfg(target_os = "linux")] pub fn set_priority(priority: i32) -> libc::c_int { set_scheduler(0, libc::SCHED_RR, priority) }