1b8a62b91Sopenharmony_ciuse rustix::time::{
2b8a62b91Sopenharmony_ci    timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags,
3b8a62b91Sopenharmony_ci    TimerfdTimerFlags, Timespec,
4b8a62b91Sopenharmony_ci};
5b8a62b91Sopenharmony_ci
6b8a62b91Sopenharmony_ci#[test]
7b8a62b91Sopenharmony_cifn test_timerfd() {
8b8a62b91Sopenharmony_ci    let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap();
9b8a62b91Sopenharmony_ci
10b8a62b91Sopenharmony_ci    let set = Itimerspec {
11b8a62b91Sopenharmony_ci        it_interval: Timespec {
12b8a62b91Sopenharmony_ci            tv_sec: 0,
13b8a62b91Sopenharmony_ci            tv_nsec: 0,
14b8a62b91Sopenharmony_ci        },
15b8a62b91Sopenharmony_ci        it_value: Timespec {
16b8a62b91Sopenharmony_ci            tv_sec: 1,
17b8a62b91Sopenharmony_ci            tv_nsec: 2,
18b8a62b91Sopenharmony_ci        },
19b8a62b91Sopenharmony_ci    };
20b8a62b91Sopenharmony_ci    let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap();
21b8a62b91Sopenharmony_ci
22b8a62b91Sopenharmony_ci    // Wait for the timer to expire.
23b8a62b91Sopenharmony_ci    let mut buf = [0_u8; 8];
24b8a62b91Sopenharmony_ci    assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8));
25b8a62b91Sopenharmony_ci    assert!(u64::from_ne_bytes(buf) >= 1);
26b8a62b91Sopenharmony_ci
27b8a62b91Sopenharmony_ci    let new = timerfd_gettime(&fd).unwrap();
28b8a62b91Sopenharmony_ci
29b8a62b91Sopenharmony_ci    // The timer counts down.
30b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec);
31b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec);
32b8a62b91Sopenharmony_ci    assert!(new.it_value.tv_sec <= set.it_value.tv_sec);
33b8a62b91Sopenharmony_ci    assert!(
34b8a62b91Sopenharmony_ci        new.it_value.tv_nsec < set.it_value.tv_nsec || new.it_value.tv_sec < set.it_value.tv_sec
35b8a62b91Sopenharmony_ci    );
36b8a62b91Sopenharmony_ci}
37b8a62b91Sopenharmony_ci
38b8a62b91Sopenharmony_ci/// Similar, but set an interval for a repeated timer. Don't check that the
39b8a62b91Sopenharmony_ci/// times are monotonic because that would race with the timer repeating.
40b8a62b91Sopenharmony_ci#[test]
41b8a62b91Sopenharmony_cifn test_timerfd_with_interval() {
42b8a62b91Sopenharmony_ci    let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap();
43b8a62b91Sopenharmony_ci
44b8a62b91Sopenharmony_ci    let set = Itimerspec {
45b8a62b91Sopenharmony_ci        it_interval: Timespec {
46b8a62b91Sopenharmony_ci            tv_sec: 0,
47b8a62b91Sopenharmony_ci            tv_nsec: 6,
48b8a62b91Sopenharmony_ci        },
49b8a62b91Sopenharmony_ci        it_value: Timespec {
50b8a62b91Sopenharmony_ci            tv_sec: 1,
51b8a62b91Sopenharmony_ci            tv_nsec: 7,
52b8a62b91Sopenharmony_ci        },
53b8a62b91Sopenharmony_ci    };
54b8a62b91Sopenharmony_ci    let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap();
55b8a62b91Sopenharmony_ci
56b8a62b91Sopenharmony_ci    // Wait for the timer to expire.
57b8a62b91Sopenharmony_ci    let mut buf = [0_u8; 8];
58b8a62b91Sopenharmony_ci    assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8));
59b8a62b91Sopenharmony_ci    assert!(u64::from_ne_bytes(buf) >= 1);
60b8a62b91Sopenharmony_ci
61b8a62b91Sopenharmony_ci    let new = timerfd_gettime(&fd).unwrap();
62b8a62b91Sopenharmony_ci
63b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec);
64b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec);
65b8a62b91Sopenharmony_ci
66b8a62b91Sopenharmony_ci    // Wait for the timer to expire again.
67b8a62b91Sopenharmony_ci    let mut buf = [0_u8; 8];
68b8a62b91Sopenharmony_ci    assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8));
69b8a62b91Sopenharmony_ci    assert!(u64::from_ne_bytes(buf) >= 1);
70b8a62b91Sopenharmony_ci
71b8a62b91Sopenharmony_ci    let new = timerfd_gettime(&fd).unwrap();
72b8a62b91Sopenharmony_ci
73b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec);
74b8a62b91Sopenharmony_ci    assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec);
75b8a62b91Sopenharmony_ci}
76