pudding_kernel/
eventflag.rs1use crate::system::*;
2use crate::*;
3
4#[derive(Clone, Copy)]
5pub enum WaitFlagMode {
6 AndWait,
7 OrWait,
8}
9
10pub 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()); 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()); 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()); 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}