Skip to content

Commit d3f167f

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

File tree

1 file changed

+112
-89
lines changed

1 file changed

+112
-89
lines changed

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

Lines changed: 112 additions & 89 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
@@ -73,82 +74,6 @@ fn test_posix_gettimeofday() {
7374
assert_eq!(is_error, -1);
7475
}
7576

76-
fn test_nanosleep() {
77-
let start_test_sleep = Instant::now();
78-
let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
79-
let remainder = ptr::null_mut::<libc::timespec>();
80-
let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) };
81-
assert_eq!(is_error, 0);
82-
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
83-
84-
let start_test_sleep = Instant::now();
85-
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
86-
let remainder = ptr::null_mut::<libc::timespec>();
87-
let is_error = unsafe { libc::nanosleep(&duration_100_millis, remainder) };
88-
assert_eq!(is_error, 0);
89-
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
90-
}
91-
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-
}
129-
130-
fn test_clock_nanosleep_relative() {
131-
const NO_FLAGS: i32 = 0;
132-
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));
141-
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));
150-
}
151-
15277
/// Helper function to create an empty tm struct.
15378
fn create_empty_tm() -> libc::tm {
15479
libc::tm {
@@ -404,3 +329,101 @@ fn test_localtime_r_multiple_calls_deduplication() {
404329
NUM_CALLS - 1
405330
);
406331
}
332+
333+
fn test_nanosleep() {
334+
let start_test_sleep = Instant::now();
335+
let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
336+
let remainder = ptr::null_mut::<libc::timespec>();
337+
let is_error = unsafe { libc::nanosleep(&duration_zero, remainder) };
338+
assert_eq!(is_error, 0);
339+
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
340+
341+
let start_test_sleep = Instant::now();
342+
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
343+
let remainder = ptr::null_mut::<libc::timespec>();
344+
let is_error = unsafe { libc::nanosleep(&duration_100_millis, remainder) };
345+
assert_eq!(is_error, 0);
346+
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
347+
}
348+
349+
#[cfg(any(
350+
target_os = "freebsd",
351+
target_os = "linux",
352+
target_os = "android",
353+
target_os = "solaris",
354+
target_os = "illumos"
355+
))]
356+
mod test_clock_nanosleep {
357+
use super::*;
358+
359+
pub fn absolute() {
360+
let start_test_sleep = Instant::now();
361+
let before_start = libc::timespec { tv_sec: 0, tv_nsec: 0 };
362+
let remainder = ptr::null_mut::<libc::timespec>();
363+
let error = unsafe {
364+
// this will not sleep since unix time zero is in the past
365+
libc::clock_nanosleep(
366+
libc::CLOCK_MONOTONIC,
367+
libc::TIMER_ABSTIME,
368+
&before_start,
369+
remainder,
370+
)
371+
};
372+
assert_eq!(error, 0);
373+
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
374+
375+
let start_test_sleep = Instant::now();
376+
let hunderd_millis_after_start = add_100_millis(timespec_now(libc::CLOCK_MONOTONIC));
377+
let remainder = ptr::null_mut::<libc::timespec>();
378+
let error = unsafe {
379+
libc::clock_nanosleep(
380+
libc::CLOCK_MONOTONIC,
381+
libc::TIMER_ABSTIME,
382+
&hunderd_millis_after_start,
383+
remainder,
384+
)
385+
};
386+
assert_eq!(error, 0);
387+
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
388+
}
389+
390+
pub fn relative() {
391+
const NO_FLAGS: i32 = 0;
392+
393+
let start_test_sleep = Instant::now();
394+
let duration_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
395+
let remainder = ptr::null_mut::<libc::timespec>();
396+
let error = unsafe {
397+
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_zero, remainder)
398+
};
399+
assert_eq!(error, 0);
400+
assert!(start_test_sleep.elapsed() < Duration::from_millis(10));
401+
402+
let start_test_sleep = Instant::now();
403+
let duration_100_millis = libc::timespec { tv_sec: 0, tv_nsec: 1_000_000_000 / 10 };
404+
let remainder = ptr::null_mut::<libc::timespec>();
405+
let error = unsafe {
406+
libc::clock_nanosleep(libc::CLOCK_MONOTONIC, NO_FLAGS, &duration_100_millis, remainder)
407+
};
408+
assert_eq!(error, 0);
409+
assert!(start_test_sleep.elapsed() > Duration::from_millis(100));
410+
}
411+
412+
/// Helper function to get the current time for testing relative sleeps
413+
fn timespec_now(clock: libc::clockid_t) -> libc::timespec {
414+
let mut timespec = mem::MaybeUninit::<libc::timespec>::uninit();
415+
let is_error = unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) };
416+
assert_eq!(is_error, 0);
417+
unsafe { timespec.assume_init() }
418+
}
419+
420+
/// Helper function used to create an instant in the future
421+
fn add_100_millis(mut ts: libc::timespec) -> libc::timespec {
422+
const SECOND: i64 = 1_000_000_000;
423+
ts.tv_nsec += ts.tv_nsec + SECOND / 10;
424+
ts.tv_nsec = ts.tv_nsec % SECOND;
425+
ts.tv_sec = ts.tv_nsec / SECOND;
426+
ts
427+
}
428+
}
429+

0 commit comments

Comments
 (0)