Skip to content
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

implement clock_gettime, clock_getres, clock_settime #1100

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased] - ReleaseDate
### Added
- Add `clock_gettime`, `clock_settime`, `clock_getres`
([#1100](https://github.com/nix-rust/nix/pull/1100))

## [0.16.0] - 1 December 2019
### Added
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub mod poll;
pub mod pty;
pub mod sched;
pub mod sys;
pub mod time;
// This can be implemented for other platforms as soon as libc
// provides bindings for them.
#[cfg(all(target_os = "linux",
Expand Down
6 changes: 6 additions & 0 deletions src/sys/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ impl AsRef<timespec> for TimeSpec {
}
}

impl From<timespec> for TimeSpec {
fn from(ts: timespec) -> Self {
TimeSpec(ts)
}
}

impl Ord for TimeSpec {
// The implementation of cmp is simplified by assuming that the struct is
// normalized. That is, tv_nsec must always be within [0, 1_000_000_000)
Expand Down
184 changes: 184 additions & 0 deletions src/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
use sys::time::TimeSpec;
use std::mem::MaybeUninit;
use {Result, Errno};
use libc;

libc_enum! {
#[cfg_attr(any(
target_env = "uclibc",
target_os = "fuchsia",
target_os = "redox",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "haiku",
all(not(target_env = "newlib"),
any(target_os = "linux",
target_os = "android",
target_os = "emscripten",
target_os = "solaris",
target_os = "illumos")),
), repr(i32))]
#[cfg_attr(any(
all(target_env = "newlib", target_arch = "arm"),
target_os = "macos",
target_os = "ios",
), repr(u32))]
#[cfg_attr(any(
all(target_env = "newlib", target_arch = "aarch64"),
all(not(any(target_env = "newlib", target_env = "uclibc")), target_os = "hermit"),
target_os = "dragonfly",
), repr(u64))]
pub enum ClockId {
#[cfg(any(target_os = "fuchsia",
all(not(any(target_env = "uclibc",
target_env = "newlib")),
any(target_os = "linux",
target_os = "android",
target_os = "emscripten"),
)
))]
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"))))]
CLOCK_BOOTTIME_ALARM,
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"))))]
CLOCK_MONOTONIC_COARSE,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_MONOTONIC_FAST,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
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"))))]
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"))))]
CLOCK_PROCESS_CPUTIME_ID,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_PROF,
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"))))]
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"))))]
CLOCK_REALTIME_COARSE,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_REALTIME_FAST,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_REALTIME_PRECISE,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
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")))))]
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")))))]
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",
),
),
)
)]
CLOCK_THREAD_CPUTIME_ID,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_UPTIME,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_UPTIME_FAST,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_UPTIME_PRECISE,
#[cfg(any(target_os = "freebsd",
target_os = "dragonfly"))]
CLOCK_VIRTUAL,
}
}

pub fn clock_getres(clk_id: ClockId) -> Result<TimeSpec> {
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
let errno = unsafe { libc::clock_getres(clk_id as libc::clockid_t, c_time.as_mut_ptr()) };
Errno::result(errno)?;
let res = unsafe { c_time.assume_init() };
Ok(TimeSpec::from(res))
}

pub fn clock_gettime(clk_id: ClockId) -> Result<TimeSpec> {
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
let errno = unsafe { libc::clock_gettime(clk_id as libc::clockid_t, c_time.as_mut_ptr()) };
Errno::result(errno)?;
let res = unsafe { c_time.assume_init() };
Ok(TimeSpec::from(res))
}

#[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(clk_id: ClockId, timespec: TimeSpec) -> Result<()> {
let res = unsafe { libc::clock_settime(clk_id as libc::clockid_t, timespec.as_ref()) };
Errno::result(res).map(drop)
}
1 change: 1 addition & 0 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ mod test_sched;
target_os = "macos"))]
mod test_sendfile;
mod test_stat;
mod test_time;
mod test_unistd;

use std::os::unix::io::RawFd;
Expand Down
11 changes: 11 additions & 0 deletions test/test_time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use nix::time::{clock_getres, clock_gettime, ClockId};

#[test]
pub fn test_clock_getres() {
assert!(clock_getres(ClockId::CLOCK_REALTIME).is_ok());
}

#[test]
pub fn test_clock_gettime() {
assert!(clock_gettime(ClockId::CLOCK_REALTIME).is_ok());
}