mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-13 15:26:48 +00:00
Add normalize for timeval_t
and const value for time
This commit is contained in:
parent
4fa4e5ef2a
commit
b4003b8aeb
@ -19,9 +19,10 @@ pub fn sys_select(
|
|||||||
let timeout = if timeval_addr == 0 {
|
let timeout = if timeval_addr == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let mut timeval = ctx.get_user_space().read_val::<timeval_t>(timeval_addr)?;
|
let timeval = ctx
|
||||||
timeval.sec += timeval.usec / 1_000_000;
|
.get_user_space()
|
||||||
timeval.usec %= 1_000_000;
|
.read_val::<timeval_t>(timeval_addr)?
|
||||||
|
.normalize();
|
||||||
Some(Duration::try_from(timeval)?)
|
Some(Duration::try_from(timeval)?)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@ pub type time_t = i64;
|
|||||||
pub type suseconds_t = i64;
|
pub type suseconds_t = i64;
|
||||||
pub type clock_t = i64;
|
pub type clock_t = i64;
|
||||||
|
|
||||||
|
const NSEC_PER_USEC: i64 = 1_000;
|
||||||
|
const USEC_PER_SEC: i64 = 1_000_000;
|
||||||
|
const NSEC_PER_SEC: i64 = 1_000_000_000;
|
||||||
|
|
||||||
pub(super) fn init() {
|
pub(super) fn init() {
|
||||||
system_time::init();
|
system_time::init();
|
||||||
clocks::init();
|
clocks::init();
|
||||||
@ -46,7 +50,7 @@ impl From<Duration> for timespec_t {
|
|||||||
impl From<timeval_t> for timespec_t {
|
impl From<timeval_t> for timespec_t {
|
||||||
fn from(timeval: timeval_t) -> timespec_t {
|
fn from(timeval: timeval_t) -> timespec_t {
|
||||||
let sec = timeval.sec;
|
let sec = timeval.sec;
|
||||||
let nsec = timeval.usec * 1000;
|
let nsec = timeval.usec * NSEC_PER_USEC;
|
||||||
debug_assert!(sec >= 0); // nsec >= 0 always holds
|
debug_assert!(sec >= 0); // nsec >= 0 always holds
|
||||||
timespec_t { sec, nsec }
|
timespec_t { sec, nsec }
|
||||||
}
|
}
|
||||||
@ -60,7 +64,7 @@ impl TryFrom<timespec_t> for Duration {
|
|||||||
return_errno_with_message!(Errno::EINVAL, "timesepc_t cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "timesepc_t cannot be negative");
|
||||||
}
|
}
|
||||||
|
|
||||||
if value.nsec > 1_000_000_000 {
|
if value.nsec > NSEC_PER_SEC {
|
||||||
// The value of nanoseconds cannot exceed 10^9,
|
// The value of nanoseconds cannot exceed 10^9,
|
||||||
// otherwise the value for seconds should be set.
|
// otherwise the value for seconds should be set.
|
||||||
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
|
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
|
||||||
@ -77,6 +81,21 @@ pub struct timeval_t {
|
|||||||
pub usec: suseconds_t,
|
pub usec: suseconds_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl timeval_t {
|
||||||
|
/// Normalizes time by adding carries from microseconds to seconds.
|
||||||
|
///
|
||||||
|
/// Some Linux system calls do this before checking the validity (e.g., the [select]
|
||||||
|
/// implementation).
|
||||||
|
///
|
||||||
|
/// [select]: https://elixir.bootlin.com/linux/v6.10.5/source/fs/select.c#L716
|
||||||
|
pub fn normalize(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
sec: self.sec.wrapping_add(self.usec / USEC_PER_SEC),
|
||||||
|
usec: self.usec % USEC_PER_SEC,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Duration> for timeval_t {
|
impl From<Duration> for timeval_t {
|
||||||
fn from(duration: Duration) -> timeval_t {
|
fn from(duration: Duration) -> timeval_t {
|
||||||
let sec = duration.as_secs() as time_t;
|
let sec = duration.as_secs() as time_t;
|
||||||
@ -93,7 +112,7 @@ impl TryFrom<timeval_t> for Duration {
|
|||||||
if timeval.sec < 0 || timeval.usec < 0 {
|
if timeval.sec < 0 || timeval.usec < 0 {
|
||||||
return_errno_with_message!(Errno::EINVAL, "timeval_t cannot be negative");
|
return_errno_with_message!(Errno::EINVAL, "timeval_t cannot be negative");
|
||||||
}
|
}
|
||||||
if timeval.usec > 1_000_000 {
|
if timeval.usec > USEC_PER_SEC {
|
||||||
// The value of microsecond cannot exceed 10^6,
|
// The value of microsecond cannot exceed 10^6,
|
||||||
// otherwise the value for seconds should be set.
|
// otherwise the value for seconds should be set.
|
||||||
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
|
return_errno_with_message!(Errno::EINVAL, "nsec is not normalized");
|
||||||
@ -101,7 +120,7 @@ impl TryFrom<timeval_t> for Duration {
|
|||||||
|
|
||||||
Ok(Duration::new(
|
Ok(Duration::new(
|
||||||
timeval.sec as u64,
|
timeval.sec as u64,
|
||||||
(timeval.usec * 1000) as u32,
|
(timeval.usec * NSEC_PER_USEC) as u32,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user