2020-04-21 18:38:14 -05:00
|
|
|
// ignore-windows: No libc on Windows
|
2020-04-30 17:37:27 -05:00
|
|
|
// ignore-macos: pthread_condattr_setclock is not supported on MacOS.
|
2020-04-21 18:38:14 -05:00
|
|
|
// compile-flags: -Zmiri-disable-isolation
|
|
|
|
|
|
|
|
#![feature(rustc_private)]
|
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
/// Test that conditional variable timeouts are working properly with both
|
|
|
|
/// monotonic and system clocks.
|
2020-04-21 18:38:14 -05:00
|
|
|
extern crate libc;
|
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
use std::mem;
|
|
|
|
use std::time::Instant;
|
2020-04-21 18:38:14 -05:00
|
|
|
|
2020-05-19 09:47:25 -05:00
|
|
|
fn test_timed_wait_timeout(clock_id: i32) {
|
2020-04-21 18:38:14 -05:00
|
|
|
unsafe {
|
2020-04-30 17:37:27 -05:00
|
|
|
let mut attr: libc::pthread_condattr_t = mem::zeroed();
|
|
|
|
assert_eq!(libc::pthread_condattr_init(&mut attr as *mut _), 0);
|
2020-05-19 09:47:25 -05:00
|
|
|
assert_eq!(libc::pthread_condattr_setclock(&mut attr as *mut _, clock_id), 0);
|
2020-04-21 18:38:14 -05:00
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
let mut cond: libc::pthread_cond_t = mem::zeroed();
|
|
|
|
assert_eq!(libc::pthread_cond_init(&mut cond as *mut _, &attr as *const _), 0);
|
|
|
|
assert_eq!(libc::pthread_condattr_destroy(&mut attr as *mut _), 0);
|
2020-04-21 18:38:14 -05:00
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
let mut mutex: libc::pthread_mutex_t = mem::zeroed();
|
2020-04-21 18:38:14 -05:00
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
let mut now: libc::timespec = mem::zeroed();
|
2020-05-19 09:47:25 -05:00
|
|
|
assert_eq!(libc::clock_gettime(clock_id, &mut now), 0);
|
2020-06-03 02:40:21 -05:00
|
|
|
// Waiting for a second... mostly because waiting less requires mich more tricky arithmetic.
|
|
|
|
// FIXME: wait less.
|
2020-04-30 17:37:27 -05:00
|
|
|
let timeout = libc::timespec { tv_sec: now.tv_sec + 1, tv_nsec: now.tv_nsec };
|
2020-04-21 18:38:14 -05:00
|
|
|
|
2020-04-30 17:37:27 -05:00
|
|
|
assert_eq!(libc::pthread_mutex_lock(&mut mutex as *mut _), 0);
|
|
|
|
let current_time = Instant::now();
|
2020-04-21 18:38:14 -05:00
|
|
|
assert_eq!(
|
2020-04-30 17:37:27 -05:00
|
|
|
libc::pthread_cond_timedwait(&mut cond as *mut _, &mut mutex as *mut _, &timeout),
|
|
|
|
libc::ETIMEDOUT
|
2020-04-21 18:38:14 -05:00
|
|
|
);
|
2020-05-19 09:47:25 -05:00
|
|
|
let elapsed_time = current_time.elapsed().as_millis();
|
2020-05-25 01:07:07 -05:00
|
|
|
assert!(900 <= elapsed_time && elapsed_time <= 1300);
|
2020-04-30 17:37:27 -05:00
|
|
|
assert_eq!(libc::pthread_mutex_unlock(&mut mutex as *mut _), 0);
|
|
|
|
assert_eq!(libc::pthread_mutex_destroy(&mut mutex as *mut _), 0);
|
|
|
|
assert_eq!(libc::pthread_cond_destroy(&mut cond as *mut _), 0);
|
2020-04-21 18:38:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2020-05-19 09:47:25 -05:00
|
|
|
test_timed_wait_timeout(libc::CLOCK_MONOTONIC);
|
|
|
|
test_timed_wait_timeout(libc::CLOCK_REALTIME);
|
2020-04-21 18:38:14 -05:00
|
|
|
}
|