Skip to content

Commit b37e03e

Browse files
committed
clock_nanosleep tests behind cfg + handle tv.nsec > 1s
1 parent 5521ed9 commit b37e03e

File tree

1 file changed

+90
-68
lines changed

1 file changed

+90
-68
lines changed

src/tools/miri/tests/pass-dep/libc/libc-time.rs

Lines changed: 90 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,9 @@ use std::{env, mem, ptr};
66
fn main() {
77
test_clocks();
88
test_posix_gettimeofday();
9-
test_nanosleep();
10-
#[cfg(any(
11-
target_os = "freebsd",
12-
target_os = "linux",
13-
target_os = "android",
14-
target_os = "solaris",
15-
target_os = "illumos"
16-
))]
17-
{
18-
test_clock_nanosleep_absolute();
19-
test_clock_nanosleep_relative();
20-
}
21-
test_localtime_r_epoch();
229
test_localtime_r_gmt();
2310
test_localtime_r_pst();
11+
test_localtime_r_epoch();
2412
#[cfg(any(
2513
target_os = "linux",
2614
target_os = "macos",
@@ -33,6 +21,19 @@ fn main() {
3321
test_localtime_r_future_32b();
3422
#[cfg(target_pointer_width = "64")]
3523
test_localtime_r_future_64b();
24+
25+
test_nanosleep();
26+
#[cfg(any(
27+
target_os = "freebsd",
28+
target_os = "linux",
29+
target_os = "android",
30+
target_os = "solaris",
31+
target_os = "illumos"
32+
))]
33+
{
34+
test_clock_nanosleep::absolute();
35+
test_clock_nanosleep::relative();
36+
}
3637
}
3738

3839
/// Tests whether clock support exists at all
@@ -89,64 +90,85 @@ fn test_nanosleep() {
8990
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
9091
}
9192

92-
/// Helper function to get the current time for testing relative sleeps
93-
fn timespec_now(clock: libc::clockid_t) -> libc::timespec {
94-
let mut timespec = mem::MaybeUninit::<libc::timespec>::uninit();
95-
let is_error = unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) };
96-
assert_eq!(is_error, 0);
97-
unsafe { timespec.assume_init() }
98-
}
99-
100-
fn test_clock_nanosleep_absolute() {
101-
let start_test_sleep = Instant::now();
102-
let before_start = libc::timespec { tv_sec: 0, tv_nsec: 0 };
103-
let remainder = ptr::null_mut::<libc::timespec>();
104-
let error = unsafe {
105-
// this will not sleep since unix time zero is in the past
106-
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, libc::TIMER_ABSTIME, &before_start, remainder)
107-
};
108-
assert_eq!(error, 0);
109-
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
110-
111-
let start_test_sleep = Instant::now();
112-
let hunderd_millis_after_start = {
113-
let mut ts = timespec_now(libc::CLOCK_MONOTONIC);
114-
ts.tv_nsec += 1_000_000_000 / 10;
115-
ts
116-
};
117-
let remainder = ptr::null_mut::<libc::timespec>();
118-
let error = unsafe {
119-
libc::clock_nanosleep(
120-
libc::CLOCK_MONOTONIC,
121-
libc::TIMER_ABSTIME,
122-
&hunderd_millis_after_start,
123-
remainder,
124-
)
125-
};
126-
assert_eq!(error, 0);
127-
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
128-
}
93+
#[cfg(any(
94+
target_os = "freebsd",
95+
target_os = "linux",
96+
target_os = "android",
97+
target_os = "solaris",
98+
target_os = "illumos"
99+
))]
100+
mod test_clock_nanosleep {
101+
use super::*;
102+
103+
pub fn absolute() {
104+
let start_test_sleep = Instant::now();
105+
let before_start = libc::timespec { tv_sec: 0, tv_nsec: 0 };
106+
let remainder = ptr::null_mut::<libc::timespec>();
107+
let error = unsafe {
108+
// this will not sleep since unix time zero is in the past
109+
libc::clock_nanosleep(
110+
libc::CLOCK_MONOTONIC,
111+
libc::TIMER_ABSTIME,
112+
&before_start,
113+
remainder,
114+
)
115+
};
116+
assert_eq!(error, 0);
117+
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
118+
119+
let start_test_sleep = Instant::now();
120+
let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC));
121+
let remainder = ptr::null_mut::<libc::timespec>();
122+
let error = unsafe {
123+
libc::clock_nanosleep(
124+
libc::CLOCK_MONOTONIC,
125+
libc::TIMER_ABSTIME,
126+
&hunderd_millis_after_start,
127+
remainder,
128+
)
129+
};
130+
assert_eq!(error, 0);
131+
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
132+
}
129133

130-
fn test_clock_nanosleep_relative() {
131-
const NO_FLAGS: i32 = 0;
134+
pub fn relative() {
135+
const NO_FLAGS: i32 = 0;
136+
137+
let start_test_sleep = Instant::now();
138+
let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
139+
let remainder = ptr::null_mut::<libc::timespec>();
140+
let error = unsafe {
141+
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)
142+
};
143+
assert_eq!(error, 0);
144+
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
145+
146+
let start_test_sleep = Instant::now();
147+
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
148+
let remainder = ptr::null_mut::<libc::timespec>();
149+
let error = unsafe {
150+
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_100_millis, remainder)
151+
};
152+
assert_eq!(error, 0);
153+
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
154+
}
132155

133-
let start_test_sleep = Instant::now();
134-
let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
135-
let remainder = ptr::null_mut::<libc::timespec>();
136-
let error = unsafe {
137-
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)
138-
};
139-
assert_eq!(error, 0);
140-
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
156+
/// Helper function to get the current time for testing relative sleeps
157+
fn timespec_now(clock: libc::clockid_t) -> libc::timespec {
158+
let mut timespec = mem::MaybeUninit::<libc::timespec>::uninit();
159+
let is_error = unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) };
160+
assert_eq!(is_error, 0);
161+
unsafe { timespec.assume_init() }
162+
}
141163

142-
let start_test_sleep = Instant::now();
143-
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
144-
let remainder = ptr::null_mut::<libc::timespec>();
145-
let error = unsafe {
146-
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_100_millis, remainder)
147-
};
148-
assert_eq!(error, 0);
149-
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
164+
/// Helper function used to create an instant in the future
165+
fn add_100_millis(mut ts: libc::timespec) -> libc::timespec {
166+
const SECOND: i64 = 1_000_000_000;
167+
ts.tv_nsec += ts.tv_nsec + SECOND / 10;
168+
ts.tv_nsec = ts.tv_nsec % SECOND;
169+
ts.tv_sec = ts.tv_nsec / SECOND;
170+
ts
171+
}
150172
}
151173

152174
/// Helper function to create an empty tm struct.

0 commit comments

Comments
 (0)