Skip to content

Commit e5b28af

Browse files
committed
shim tests adds nanosleep and clock nanosleep
1 parent 1ca609d commit e5b28af

File tree

1 file changed

+98
-1
lines changed

1 file changed

+98
-1
lines changed

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

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
//@ignore-target: windows # no libc time APIs on Windows
22
//@compile-flags: -Zmiri-disable-isolation
33
use std::{env, mem, ptr};
4+
use std::time::{Duration, Instant};
45

56
fn main() {
67
test_clocks();
78
test_posix_gettimeofday();
9+
test_nanosleep();
10+
test_clock_nanosleep_absolute();
11+
test_clock_nanosleep_relative();
12+
test_localtime_r_epoch();
813
test_localtime_r_gmt();
914
test_localtime_r_pst();
10-
test_localtime_r_epoch();
1115
#[cfg(any(
1216
target_os = "linux",
1317
target_os = "macos",
@@ -60,6 +64,99 @@ fn test_posix_gettimeofday() {
6064
assert_eq!(is_error, -1);
6165
}
6266

67+
fn test_nanosleep() {
68+
// sleep zero seconds
69+
let start_zero_second_sleep = Instant::now();
70+
let timespec = libc::timespec { tv_sec: 0, tv_nsec: 0 };
71+
let remainder = ptr::null_mut::<libc::timespec>();
72+
let is_error = unsafe { libc::nanosleep(&timespec, remainder) };
73+
assert_eq!(is_error, 0);
74+
assert!(start_zero_second_sleep.elapsed() < Duration::from_millis(100));
75+
76+
// sleep one second
77+
let start_one_second_sleep = Instant::now();
78+
let timespec = libc::timespec { tv_sec: 1, tv_nsec: 0 };
79+
let remainder = ptr::null_mut::<libc::timespec>();
80+
let is_error = unsafe { libc::nanosleep(&timespec, remainder) };
81+
assert_eq!(is_error, 0);
82+
assert!(start_one_second_sleep.elapsed() > Duration::from_secs(1));
83+
}
84+
85+
/// Helper function to get the current time for testing relative sleeps
86+
fn timespec_now(clock: libc::clockid_t) -> libc::timespec {
87+
let mut timespec = mem::MaybeUninit::<libc::timespec>::uninit();
88+
let is_error = unsafe { libc::clock_gettime(clock, timespec.as_mut_ptr()) };
89+
assert_eq!(is_error, 0);
90+
unsafe { timespec.assume_init() }
91+
}
92+
93+
fn test_clock_nanosleep_absolute() {
94+
let start_zero_second_sleep = Instant::now();
95+
let unix_time_zero = libc::timespec { tv_sec: 0, tv_nsec: 0 };
96+
let remainder = ptr::null_mut::<libc::timespec>();
97+
let error = unsafe {
98+
// this will not sleep since unix time zero is in the past
99+
libc::clock_nanosleep(
100+
libc::CLOCK_MONOTONIC,
101+
libc::TIMER_ABSTIME,
102+
&unix_time_zero,
103+
remainder,
104+
)
105+
};
106+
assert_eq!(error, 0);
107+
assert!(start_zero_second_sleep.elapsed() < Duration::from_millis(100));
108+
109+
let start_one_second_sleep = Instant::now();
110+
let mut one_second_from_now = timespec_now(libc::CLOCK_MONOTONIC);
111+
one_second_from_now.tv_sec += 1;
112+
let remainder = ptr::null_mut::<libc::timespec>();
113+
let error = unsafe {
114+
// this will not sleep since unix time zero is in the past
115+
libc::clock_nanosleep(
116+
libc::CLOCK_MONOTONIC,
117+
libc::TIMER_ABSTIME,
118+
&one_second_from_now,
119+
remainder,
120+
)
121+
};
122+
assert_eq!(error, 0);
123+
assert!(start_one_second_sleep.elapsed() > Duration::from_secs(1));
124+
}
125+
126+
fn test_clock_nanosleep_relative() {
127+
const NO_FLAGS: i32 = 0;
128+
129+
let start_zero_second_sleep = Instant::now();
130+
let zero_seconds = libc::timespec { tv_sec: 0, tv_nsec: 0 };
131+
let remainder = ptr::null_mut::<libc::timespec>();
132+
let error = unsafe {
133+
// this will not sleep since unix time zero is in the past
134+
libc::clock_nanosleep(
135+
libc::CLOCK_MONOTONIC,
136+
NO_FLAGS,
137+
&zero_seconds,
138+
remainder,
139+
)
140+
};
141+
assert_eq!(error, 0);
142+
assert!(start_zero_second_sleep.elapsed() < Duration::from_millis(100));
143+
144+
let start_one_second_sleep = Instant::now();
145+
let one_second = libc::timespec { tv_sec: 1, tv_nsec: 0 };
146+
let remainder = ptr::null_mut::<libc::timespec>();
147+
let error = unsafe {
148+
// this will not sleep since unix time zero is in the past
149+
libc::clock_nanosleep(
150+
libc::CLOCK_MONOTONIC,
151+
NO_FLAGS,
152+
&one_second,
153+
remainder,
154+
)
155+
};
156+
assert_eq!(error, 0);
157+
assert!(start_one_second_sleep.elapsed() > Duration::from_secs(1));
158+
}
159+
63160
/// Helper function to create an empty tm struct.
64161
fn create_empty_tm() -> libc::tm {
65162
libc::tm {

0 commit comments

Comments
 (0)