pudding_kernel/
eventflag.rs

1use crate::system::*;
2use crate::*;
3
4#[derive(Clone, Copy)]
5pub enum WaitFlagMode {
6    AndWait,
7    OrWait,
8}
9
10// EventFlag control block
11pub struct Eventflag {
12    queue: TaskQueue,
13    flg_ptn: FlagPattern,
14    wait_ptn: FlagPattern,
15    wait_mode: WaitFlagMode,
16}
17
18impl Eventflag {
19    pub const fn new(init_pattern: FlagPattern) -> Self {
20        Eventflag {
21            queue: TaskQueue::new(),
22            flg_ptn: init_pattern,
23            wait_ptn: 0,
24            wait_mode: WaitFlagMode::AndWait,
25        }
26    }
27
28    fn is_match_pattern(&self) -> bool {
29        match self.wait_mode {
30            WaitFlagMode::AndWait => (self.flg_ptn & self.wait_ptn) == self.wait_ptn,
31            WaitFlagMode::OrWait => (self.flg_ptn & self.wait_ptn) != 0,
32        }
33    }
34
35    pub fn set_flag(&mut self, pattern: FlagPattern) {
36        let _sc = SystemCall::new();
37        self.flg_ptn |= pattern;
38        let front = self.queue.front();
39        match front {
40            None => {}
41            Some(task) => {
42                if self.is_match_pattern() {
43                    task.detach_from_queue();
44                    task.detach_from_timeout();
45                    task.attach_to_ready_queue();
46                    set_dispatch_reserve_flag();
47                }
48            }
49        }
50    }
51
52    pub fn clear_flag(&mut self, pattern: FlagPattern) {
53        let _sc = SystemCall::new();
54        self.flg_ptn &= pattern;
55    }
56
57    pub fn wait(&mut self, wait_pattern: FlagPattern, wait_mode: WaitFlagMode) {
58        let _sc = SystemCall::new();
59        assert!(self.queue.is_empty()); // TA_WSGL のみ
60
61        self.wait_ptn = wait_pattern;
62        self.wait_mode = wait_mode;
63        if !self.is_match_pattern() {
64            let task = detach_current_task().unwrap();
65            task.attach_to_queue(&mut self.queue, Order::Fifo);
66            set_dispatch_reserve_flag();
67        }
68    }
69
70    pub fn polling(
71        &mut self,
72        wait_pattern: FlagPattern,
73        wait_mode: WaitFlagMode,
74    ) -> Result<(), Error> {
75        let _sc = SystemCall::new();
76        assert!(self.queue.is_empty()); // TA_WSGL のみ
77        self.wait_ptn = wait_pattern;
78        self.wait_mode = wait_mode;
79        if self.is_match_pattern() {
80            Ok(())
81        } else {
82            Err(Error::Timeout)
83        }
84    }
85
86    pub fn wait_with_timeout(
87        &mut self,
88        wait_pattern: FlagPattern,
89        wait_mode: WaitFlagMode,
90        time: RelativeTime,
91    ) -> Result<(), Error> {
92        let task = current_task().unwrap();
93        {
94            let _sc = SystemCall::new();
95            assert!(self.queue.is_empty()); // TA_WSGL のみ
96
97            self.wait_ptn = wait_pattern;
98            self.wait_mode = wait_mode;
99            if self.is_match_pattern() {
100                task.set_result(Ok(()));
101            } else {
102                task.detach_from_queue();
103                task.attach_to_queue(&mut self.queue, Order::Fifo);
104                task.attach_to_timeout(time);
105                set_dispatch_reserve_flag();
106            }
107        }
108        task.result()
109    }
110}