xref: /DragonOS/kernel/crates/wait_queue_macros/src/lib.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
1 #![no_std]
2 
3 /// Wait for a condition to become true.
4 ///
5 /// This macro will wait for a condition to become true.
6 ///
7 /// ## Parameters
8 ///
9 /// - `$wq`: The wait queue to wait on.
10 /// - `$condition`: The condition to wait for. (you can pass a function or a boolean expression)
11 /// - `$cmd`: The command to execute while waiting.
12 #[macro_export]
13 macro_rules! wq_wait_event_interruptible {
14     ($wq:expr, $condition: expr, $cmd: expr) => {{
15         let mut retval = Ok(());
16         if !$condition {
17             retval = wait_queue_macros::_wq_wait_event_interruptible!($wq, $condition, $cmd);
18         }
19 
20         retval
21     }};
22 }
23 
24 #[macro_export]
25 #[allow(clippy::crate_in_macro_def)]
26 macro_rules! _wq_wait_event_interruptible {
27     ($wq:expr, $condition: expr, $cmd: expr) => {{
28         wait_queue_macros::__wq_wait_event!($wq, $condition, true, Ok(()), {
29             $cmd;
30             crate::sched::schedule(SchedMode::SM_NONE)
31         })
32     }};
33 }
34 
35 #[macro_export]
36 macro_rules! __wq_wait_event(
37     ($wq:expr, $condition: expr, $interruptible: expr, $ret: expr, $cmd:expr) => {{
38         let mut retval = $ret;
39         let mut exec_finish_wait = true;
40         loop {
41             let x = $wq.prepare_to_wait_event($interruptible);
42             if $condition {
43                 break;
44             }
45 
46             if $interruptible && !x.is_ok() {
47                 retval = x;
48                 exec_finish_wait = false;
49                 break;
50             }
51 
52             $cmd;
53         }
54         if exec_finish_wait {
55             $wq.finish_wait();
56         }
57 
58         retval
59     }};
60 );
61