-
Notifications
You must be signed in to change notification settings - Fork 673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added clock_gettime, clock_getres, clock_settime, clock_getcpuclockid #1281
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
use crate::sys::time::TimeSpec; | ||
#[cfg(any( | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
target_os = "linux", | ||
target_os = "android", | ||
target_os = "emscripten", | ||
))] | ||
use crate::{unistd::Pid, Error}; | ||
use crate::{Errno, Result}; | ||
use libc::{self, clockid_t}; | ||
use std::mem::MaybeUninit; | ||
|
||
/// Clock identifier | ||
/// | ||
/// Newtype pattern around `clockid_t` (which is just alias). It pervents bugs caused by | ||
/// accidentally passing wrong value. | ||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] | ||
pub struct ClockId(clockid_t); | ||
|
||
impl ClockId { | ||
/// Creates `ClockId` from raw `clockid_t` | ||
pub fn from_raw(clk_id: clockid_t) -> Self { | ||
ClockId(clk_id) | ||
} | ||
|
||
/// Returns `ClockId` of a `pid` CPU-time clock | ||
#[cfg(any( | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
target_os = "linux", | ||
target_os = "android", | ||
target_os = "emscripten", | ||
))] | ||
pub fn pid_cpu_clock_id(pid: Pid) -> Result<Self> { | ||
clock_getcpuclockid(pid) | ||
xonatius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/// Returns resolution of the clock id | ||
pub fn res(self) -> Result<TimeSpec> { | ||
clock_getres(self) | ||
} | ||
|
||
/// Returns the current time on the clock id | ||
pub fn now(self) -> Result<TimeSpec> { | ||
clock_gettime(self) | ||
} | ||
|
||
/// Sets time to `timespec` on the clock id | ||
#[cfg(not(any( | ||
target_os = "macos", | ||
target_os = "ios", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlibc")), | ||
any(target_os = "redox", target_os = "hermit",), | ||
), | ||
)))] | ||
pub fn set_time(self, timespec: TimeSpec) -> Result<()> { | ||
clock_settime(self, timespec) | ||
} | ||
|
||
/// Gets the raw `clockid_t` wrapped by `self` | ||
pub fn as_raw(self) -> clockid_t { | ||
self.0 | ||
} | ||
|
||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten"), | ||
) | ||
))] | ||
pub const CLOCK_BOOTTIME: ClockId = ClockId(libc::CLOCK_BOOTTIME); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_BOOTTIME_ALARM: ClockId = ClockId(libc::CLOCK_BOOTTIME_ALARM); | ||
pub const CLOCK_MONOTONIC: ClockId = ClockId(libc::CLOCK_MONOTONIC); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_MONOTONIC_COARSE: ClockId = ClockId(libc::CLOCK_MONOTONIC_COARSE); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_MONOTONIC_FAST: ClockId = ClockId(libc::CLOCK_MONOTONIC_FAST); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_MONOTONIC_PRECISE: ClockId = ClockId(libc::CLOCK_MONOTONIC_PRECISE); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_MONOTONIC_RAW: ClockId = ClockId(libc::CLOCK_MONOTONIC_RAW); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
target_env = "uclibc", | ||
target_os = "macos", | ||
target_os = "ios", | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
all( | ||
not(target_env = "newlib"), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_PROCESS_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_PROCESS_CPUTIME_ID); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_PROF: ClockId = ClockId(libc::CLOCK_PROF); | ||
pub const CLOCK_REALTIME: ClockId = ClockId(libc::CLOCK_REALTIME); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_REALTIME_ALARM: ClockId = ClockId(libc::CLOCK_REALTIME_ALARM); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten") | ||
) | ||
))] | ||
pub const CLOCK_REALTIME_COARSE: ClockId = ClockId(libc::CLOCK_REALTIME_COARSE); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_REALTIME_FAST: ClockId = ClockId(libc::CLOCK_REALTIME_FAST); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_REALTIME_PRECISE: ClockId = ClockId(libc::CLOCK_REALTIME_PRECISE); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_SECOND: ClockId = ClockId(libc::CLOCK_SECOND); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any( | ||
target_os = "emscripten", | ||
all(target_os = "linux", target_env = "musl") | ||
) | ||
) | ||
))] | ||
pub const CLOCK_SGI_CYCLE: ClockId = ClockId(libc::CLOCK_SGI_CYCLE); | ||
#[cfg(any( | ||
target_os = "fuchsia", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlib")), | ||
any( | ||
target_os = "emscripten", | ||
all(target_os = "linux", target_env = "musl") | ||
) | ||
) | ||
))] | ||
pub const CLOCK_TAI: ClockId = ClockId(libc::CLOCK_TAI); | ||
#[cfg(any( | ||
target_env = "uclibc", | ||
target_os = "fuchsia", | ||
target_os = "ios", | ||
target_os = "macos", | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
all( | ||
not(target_env = "newlib"), | ||
any(target_os = "linux", target_os = "android", target_os = "emscripten",), | ||
), | ||
))] | ||
pub const CLOCK_THREAD_CPUTIME_ID: ClockId = ClockId(libc::CLOCK_THREAD_CPUTIME_ID); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_UPTIME: ClockId = ClockId(libc::CLOCK_UPTIME); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_UPTIME_FAST: ClockId = ClockId(libc::CLOCK_UPTIME_FAST); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_UPTIME_PRECISE: ClockId = ClockId(libc::CLOCK_UPTIME_PRECISE); | ||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] | ||
pub const CLOCK_VIRTUAL: ClockId = ClockId(libc::CLOCK_VIRTUAL); | ||
} | ||
|
||
impl Into<clockid_t> for ClockId { | ||
fn into(self) -> clockid_t { | ||
self.as_raw() | ||
} | ||
} | ||
|
||
impl From<clockid_t> for ClockId { | ||
fn from(clk_id: clockid_t) -> Self { | ||
ClockId::from_raw(clk_id) | ||
} | ||
} | ||
|
||
impl std::fmt::Display for ClockId { | ||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&self.0, f) | ||
} | ||
} | ||
|
||
/// Get the resolution of the specified clock, (see | ||
/// [clock_getres(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_getres.html)). | ||
pub fn clock_getres(clock_id: ClockId) -> Result<TimeSpec> { | ||
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit(); | ||
let ret = unsafe { libc::clock_getres(clock_id.as_raw(), c_time.as_mut_ptr()) }; | ||
Errno::result(ret)?; | ||
let res = unsafe { c_time.assume_init() }; | ||
Ok(TimeSpec::from(res)) | ||
} | ||
|
||
/// Get the time of the specified clock, (see | ||
/// [clock_gettime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_gettime.html)). | ||
pub fn clock_gettime(clock_id: ClockId) -> Result<TimeSpec> { | ||
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit(); | ||
let ret = unsafe { libc::clock_gettime(clock_id.as_raw(), c_time.as_mut_ptr()) }; | ||
Errno::result(ret)?; | ||
let res = unsafe { c_time.assume_init() }; | ||
Ok(TimeSpec::from(res)) | ||
} | ||
|
||
/// Set the time of the specified clock, (see | ||
/// [clock_settime(2)](https://pubs.opengroup.org/onlinepubs/7908799/xsh/clock_settime.html)). | ||
#[cfg(not(any( | ||
target_os = "macos", | ||
target_os = "ios", | ||
all( | ||
not(any(target_env = "uclibc", target_env = "newlibc")), | ||
any(target_os = "redox", target_os = "hermit",), | ||
), | ||
)))] | ||
pub fn clock_settime(clock_id: ClockId, timespec: TimeSpec) -> Result<()> { | ||
let ret = unsafe { libc::clock_settime(clock_id.as_raw(), timespec.as_ref()) }; | ||
Errno::result(ret).map(drop) | ||
} | ||
|
||
/// Get the clock id of the specified process id, (see | ||
/// [clock_getcpuclockid(3)](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_getcpuclockid.html)). | ||
#[cfg(any( | ||
target_os = "freebsd", | ||
target_os = "dragonfly", | ||
target_os = "linux", | ||
target_os = "android", | ||
target_os = "emscripten", | ||
))] | ||
pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> { | ||
let mut clk_id: MaybeUninit<libc::clockid_t> = MaybeUninit::uninit(); | ||
let ret = unsafe { libc::clock_getcpuclockid(pid.into(), clk_id.as_mut_ptr()) }; | ||
if ret == 0 { | ||
let res = unsafe { clk_id.assume_init() }; | ||
Ok(ClockId::from(res)) | ||
} else { | ||
Err(Error::Sys(Errno::from_i32(ret))) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this use
libc_enum!
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enum won't work for
clockid_t
returned byclock_getcpuclockid
, that's why I had to go with struct.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're worried that the OS may add a new clockid that Nix doesn't know about? Ok, that's a fair reason.