1pub fn ax_sleep_until(deadline: crate::time::AxTimeValue) {
2 #[cfg(feature = "multitask")]
3 axtask::sleep_until(deadline);
4 #[cfg(not(feature = "multitask"))]
5 axhal::time::busy_wait_until(deadline);
6}
7
8pub fn ax_yield_now() {
9 #[cfg(feature = "multitask")]
10 axtask::yield_now();
11 #[cfg(not(feature = "multitask"))]
12 if cfg!(feature = "irq") {
13 axhal::arch::wait_for_irqs();
14 } else {
15 core::hint::spin_loop();
16 }
17}
18
19pub fn ax_exit(_exit_code: i32) -> ! {
20 #[cfg(feature = "multitask")]
21 axtask::exit(_exit_code);
22 #[cfg(not(feature = "multitask"))]
23 axhal::misc::terminate();
24}
25
26cfg_task! {
27 use core::time::Duration;
28
29 pub struct AxTaskHandle {
31 inner: axtask::AxTaskRef,
32 id: u64,
33 }
34
35 impl AxTaskHandle {
36 pub fn id(&self) -> u64 {
38 self.id
39 }
40 }
41
42 pub use axtask::AxCpuMask;
44
45 pub struct AxWaitQueueHandle(axtask::WaitQueue);
50
51 impl AxWaitQueueHandle {
52 pub const fn new() -> Self {
54 Self(axtask::WaitQueue::new())
55 }
56 }
57
58 pub fn ax_current_task_id() -> u64 {
59 axtask::current().id().as_u64()
60 }
61
62 pub fn ax_spawn<F>(f: F, name: alloc::string::String, stack_size: usize) -> AxTaskHandle
63 where
64 F: FnOnce() + Send + 'static,
65 {
66 let inner = axtask::spawn_raw(f, name, stack_size);
67 AxTaskHandle {
68 id: inner.id().as_u64(),
69 inner,
70 }
71 }
72
73 pub fn ax_wait_for_exit(task: AxTaskHandle) -> Option<i32> {
74 task.inner.join()
75 }
76
77 pub fn ax_set_current_priority(prio: isize) -> crate::AxResult {
78 if axtask::set_priority(prio) {
79 Ok(())
80 } else {
81 axerrno::ax_err!(
82 BadState,
83 "ax_set_current_priority: failed to set task priority"
84 )
85 }
86 }
87
88 pub fn ax_set_current_affinity(cpumask: AxCpuMask) -> crate::AxResult {
89 if axtask::set_current_affinity(cpumask) {
90 Ok(())
91 } else {
92 axerrno::ax_err!(
93 BadState,
94 "ax_set_current_affinity: failed to set task affinity"
95 )
96 }
97 }
98
99 pub fn ax_wait_queue_wait(wq: &AxWaitQueueHandle, timeout: Option<Duration>) -> bool {
100 #[cfg(feature = "irq")]
101 if let Some(dur) = timeout {
102 return wq.0.wait_timeout(dur);
103 }
104
105 if timeout.is_some() {
106 axlog::warn!("ax_wait_queue_wait: the `timeout` argument is ignored without the `irq` feature");
107 }
108 wq.0.wait();
109 false
110 }
111
112 pub fn ax_wait_queue_wait_until(
113 wq: &AxWaitQueueHandle,
114 until_condition: impl Fn() -> bool,
115 timeout: Option<Duration>,
116 ) -> bool {
117 #[cfg(feature = "irq")]
118 if let Some(dur) = timeout {
119 return wq.0.wait_timeout_until(dur, until_condition);
120 }
121
122 if timeout.is_some() {
123 axlog::warn!("ax_wait_queue_wait_until: the `timeout` argument is ignored without the `irq` feature");
124 }
125 wq.0.wait_until(until_condition);
126 false
127 }
128
129 pub fn ax_wait_queue_wake(wq: &AxWaitQueueHandle, count: u32) {
130 if count == u32::MAX {
131 wq.0.notify_all(true);
132 } else {
133 for _ in 0..count {
134 wq.0.notify_one(true);
135 }
136 }
137 }
138}