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