use std::convert::TryFrom;
#[must_use]
pub fn nano_ts() -> u128 { time::nano_ts() }
#[must_use]
pub fn second_ts() -> u64 { time::second_ts() }
#[must_use]
pub fn num_cores() -> u64 { cpu::num_cores() }
#[must_use]
pub fn num_available_cores() -> u64 { cpu::num_available_cores() }
#[must_use]
pub fn terminal_width(stream: atty::Stream) -> Option<usize> { terminal::width(stream) }
pub fn remap<S, D: TryFrom<S> + From<bool>>(num: S) -> D {
match D::try_from(num) {
Ok(d) => d,
Err(_) => D::from(false),
}
}
#[cfg(target_os = "linux")]
mod time {
use super::remap;
use libc::{clock_gettime, timespec, CLOCK_REALTIME};
use std::mem;
fn get_time() -> timespec {
let mut tp: timespec = unsafe { mem::zeroed() };
unsafe {
clock_gettime(CLOCK_REALTIME, &mut tp);
}
tp
}
pub fn nano_ts() -> u128 {
let tp = get_time();
remap::<_, u128>(tp.tv_nsec) + (remap::<_, u128>(tp.tv_sec) * 1_000_000_000)
}
pub fn second_ts() -> u64 { remap::<_, u64>(get_time().tv_sec) }
}
#[cfg(target_os = "linux")]
mod cpu {
use super::remap;
use libc::{c_long, sysconf, _SC_NPROCESSORS_CONF, _SC_NPROCESSORS_ONLN};
pub fn num_cores() -> u64 {
let count: c_long = unsafe { sysconf(_SC_NPROCESSORS_CONF) };
remap::<_, u64>(count)
}
pub fn num_available_cores() -> u64 {
let count: c_long = unsafe { sysconf(_SC_NPROCESSORS_ONLN) };
remap::<_, u64>(count)
}
}
#[cfg(target_os = "linux")]
mod terminal {
use std::mem;
pub fn width(stream: atty::Stream) -> Option<usize> {
unsafe {
let mut winsize: libc::winsize = mem::zeroed();
let fileno = match stream {
atty::Stream::Stdout => libc::STDOUT_FILENO,
_ => libc::STDERR_FILENO,
};
if libc::ioctl(fileno, libc::TIOCGWINSZ, &mut winsize) < 0 {
return None;
}
if winsize.ws_col > 0 {
Some(winsize.ws_col as usize)
} else {
None
}
}
}
}