starnix_core/fs/fuchsia/
timer.rs1use crate::power::OnWakeOps;
6use crate::task::{CurrentTask, Kernel};
7use crate::time::TargetTime;
8use crate::time::utc::estimate_boot_deadline_from_utc;
9use crate::vfs::timer::{TimelineChangeObserver, TimerOps};
10use starnix_uapi::errors::Errno;
11use starnix_uapi::{error, from_status_like_fdio};
12use std::sync::{Arc, Weak};
13use zx::HandleRef;
14
15pub struct MonotonicZxTimer {
16 timer: zx::MonotonicTimer,
17}
18
19impl MonotonicZxTimer {
20 pub fn new() -> Self {
21 Self { timer: zx::MonotonicTimer::create() }
22 }
23}
24
25impl TimerOps for MonotonicZxTimer {
26 fn start(
27 &self,
28 current_task: &CurrentTask,
29 _source: Option<Weak<dyn OnWakeOps>>,
30 deadline: TargetTime,
31 ) -> Result<(), Errno> {
32 let timerslack = current_task.read().get_timerslack();
33 match deadline {
34 TargetTime::Monotonic(t) => {
35 self.timer.set(t, timerslack).map_err(|status| from_status_like_fdio!(status))?
36 }
37 TargetTime::BootInstant(_) | TargetTime::RealTime(_) => return error!(EINVAL),
38 };
39
40 Ok(())
41 }
42
43 fn stop(&self, _kernel: &Arc<Kernel>) -> Result<(), Errno> {
44 self.timer.cancel().map_err(|status| from_status_like_fdio!(status))
45 }
46
47 fn as_handle_ref(&self) -> HandleRef<'_> {
48 self.timer.as_handle_ref()
49 }
50
51 fn get_timeline_change_observer(&self, _: &CurrentTask) -> Option<TimelineChangeObserver> {
53 None
54 }
55}
56
57pub struct BootZxTimer {
58 timer: zx::BootTimer,
59}
60
61impl BootZxTimer {
62 pub fn new() -> Self {
63 Self { timer: zx::BootTimer::create() }
64 }
65}
66
67impl TimerOps for BootZxTimer {
68 fn start(
69 &self,
70 current_task: &CurrentTask,
71 _source: Option<Weak<dyn OnWakeOps>>,
72 deadline: TargetTime,
73 ) -> Result<(), Errno> {
74 let timerslack = current_task.read().get_timerslack();
75 match deadline {
76 TargetTime::BootInstant(t) => {
77 self.timer.set(t, timerslack).map_err(|status| from_status_like_fdio!(status))?
78 }
79 TargetTime::RealTime(t) => {
80 let (boot_instant, _) = estimate_boot_deadline_from_utc(t);
81 self.timer
82 .set(boot_instant, timerslack)
83 .map_err(|status| from_status_like_fdio!(status))?
84 }
85 TargetTime::Monotonic(_) => return error!(EINVAL),
86 }
87 Ok(())
88 }
89
90 fn stop(&self, _kernel: &Arc<Kernel>) -> Result<(), Errno> {
91 self.timer.cancel().map_err(|status| from_status_like_fdio!(status))
92 }
93
94 fn as_handle_ref(&self) -> HandleRef<'_> {
95 self.timer.as_handle_ref()
96 }
97
98 fn get_timeline_change_observer(&self, _: &CurrentTask) -> Option<TimelineChangeObserver> {
100 None
101 }
102}