1use core::sync::atomic::Ordering;
4
5use alloc::{collections::vec_deque::VecDeque, vec::Vec};
6
7use crate::{
8 kernel::{WaitQueue, current_cpu, current_task, yield_task},
9 sync::{Mutex, SpinLock},
10};
11
12const DEFAULT_QUEUE_BYTES: usize = 1024;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct Message {
18 pub mtype: i32,
20 pub msize: usize,
22 pub mtext: Vec<u8>,
24}
25
26impl Message {
27 pub fn new(mtype: i32, mtext: Vec<u8>) -> Self {
29 let msize = mtext.len();
30 Message {
31 mtype,
32 msize,
33 mtext,
34 }
35 }
36}
37
38struct QueueState {
40 messages: VecDeque<Message>,
41 bytes: usize,
42}
43
44impl QueueState {
45 fn new() -> Self {
46 Self {
47 messages: VecDeque::new(),
48 bytes: 0,
49 }
50 }
51}
52
53pub struct MessageQueue {
55 state: Mutex<QueueState>,
57 send_waiters: SpinLock<WaitQueue>,
59 recv_waiters: SpinLock<WaitQueue>,
61 max_bytes: usize,
63}
64
65impl MessageQueue {
66 pub fn new() -> Self {
68 MessageQueue {
69 state: Mutex::new(QueueState::new()),
70 send_waiters: SpinLock::new(WaitQueue::new()),
71 recv_waiters: SpinLock::new(WaitQueue::new()),
72 max_bytes: DEFAULT_QUEUE_BYTES,
73 }
74 }
75
76 pub fn send(&self, msg: Message) {
78 let size = msg.msize;
79 let mut pending = Some(msg); loop {
81 let mut st = self.state.lock();
82 if st.bytes + size <= self.max_bytes {
83 let m = pending.take().expect("message already taken");
84 st.bytes += size;
85 st.messages.push_back(m);
86 self.recv_waiters.lock().wake_up_all();
87 return;
88 }
89
90 drop(st);
92 self.send_waiters.lock().sleep(current_task());
93 }
95 }
96
97 pub fn recv(&self) -> Message {
99 loop {
100 if let Some(msg) = {
101 let mut st = self.state.lock();
102 match st.messages.pop_front() {
103 Some(m) => {
104 st.bytes -= m.msize;
105 Some(m)
106 }
107 None => None,
108 }
109 } {
110 self.send_waiters.lock().wake_up_all();
111 return msg;
112 }
113
114 self.recv_waiters.lock().sleep(current_task());
115 }
116 }
117
118 pub fn recv_by_type(&self, mtype: i32) -> Message {
120 loop {
121 if let Some(msg) = {
122 let mut st = self.state.lock();
123 if let Some(i) = st.messages.iter().position(|m| m.mtype == mtype) {
124 let m = st.messages.remove(i).unwrap();
125 st.bytes -= m.msize;
126 Some(m)
127 } else {
128 None
129 }
130 } {
131 self.send_waiters.lock().wake_up_all();
132 return msg;
133 }
134
135 self.recv_waiters.lock().sleep(current_task());
136 }
137 }
138
139 pub fn try_send(&self, msg: Message) -> bool {
141 let mut st = self.state.lock();
142 if st.bytes + msg.msize <= self.max_bytes {
143 st.bytes += msg.msize;
144 st.messages.push_back(msg);
145 drop(st);
146 self.recv_waiters.lock().wake_up_all();
147 true
148 } else {
149 false
150 }
151 }
152
153 pub fn try_recv(&self) -> Option<Message> {
155 let mut st = self.state.lock();
156 let msg = st.messages.pop_front()?;
157 st.bytes -= msg.msize;
158 drop(st);
159 self.send_waiters.lock().wake_up_all();
160 Some(msg)
161 }
162
163 pub fn try_recv_by_type(&self, mtype: i32) -> Option<Message> {
165 let mut st = self.state.lock();
166 let ix = st.messages.iter().position(|m| m.mtype == mtype)?;
167 let msg = st.messages.remove(ix).unwrap();
168 st.bytes -= msg.msize;
169 drop(st);
170 self.send_waiters.lock().wake_up_all();
171 Some(msg)
172 }
173
174 pub fn used_bytes(&self) -> usize {
176 self.state.lock().bytes
177 }
178
179 pub fn set_max_bytes(&mut self, max: usize) {
181 let mut st = self.state.lock();
182 st.bytes = st.bytes.min(max);
183 self.max_bytes = max;
184 drop(st);
186 self.send_waiters.lock().wake_up_all();
187 }
188}