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