1use super::array::Vec;
4use super::boxed::Box;
5use crate::utils::KernelError;
6
7pub struct Queue<T: Clone, const N: usize> {
9 data: Vec<T, N>,
10 len: usize,
11 front: usize,
12}
13
14impl<T: Clone + Copy, const N: usize> Queue<T, N> {
15 pub const fn new() -> Self {
17 Self {
18 data: Vec::new(),
19 len: 0,
20 front: 0,
21 }
22 }
23
24 pub fn push_back(&mut self, value: T) -> Result<(), KernelError> {
30 if self.len == self.data.capacity() {
31 return Err(KernelError::OutOfMemory);
32 }
33 self.len += 1;
34 if self.data.len() != self.data.capacity() {
35 self.data.push(value)?;
36 } else {
37 self.insert(self.len - 1, value)?;
38 }
39
40 Ok(())
41 }
42
43 pub fn pop_front(&mut self) -> Option<T> {
47 if self.len == 0 {
48 return None;
49 }
50
51 let value = self.data.at(self.front).cloned();
52
53 self.front = (self.front + 1) % self.data.capacity();
54 self.len -= 1;
55 value
56 }
57
58 pub fn insert(&mut self, index: usize, value: T) -> Result<(), KernelError> {
65 if index >= self.len() {
66 return Err(KernelError::InvalidAddress);
67 }
68 let real_idx = (self.front + index) % self.data.capacity();
69 self.data
70 .at_mut(real_idx)
71 .map(|insertion_point| *insertion_point = value)
72 .ok_or(KernelError::InvalidAddress)
73 }
74
75 pub fn front(&self) -> Option<&T> {
77 if self.is_empty() {
78 return None;
79 }
80
81 self.data.at(self.front)
82 }
83
84 pub fn back(&self) -> Option<&T> {
86 if self.is_empty() {
87 return None;
88 }
89 let back = (self.front + self.len - 1) % self.data.capacity();
90 self.data.at(back)
91 }
92
93 pub fn len(&self) -> usize {
95 self.len
96 }
97
98 pub fn is_empty(&self) -> bool {
100 self.len == 0
101 }
102
103 pub fn grow_capacity(&mut self, new_size: usize) -> Result<(), KernelError> {
110 if new_size <= self.data.capacity() {
111 return Ok(());
112 }
113 if self.front + self.len >= self.data.capacity() {
115 let non_wrapping_queue_start_len = self.data.capacity() - self.front;
120 let mut swap_helper = Box::new_slice_uninit(non_wrapping_queue_start_len)?;
121 BUG_ON!(swap_helper.len() != non_wrapping_queue_start_len);
122
123 for i in 0..swap_helper.len() {
125 swap_helper[i].write(
127 self.data
128 .at(self.front + i)
129 .copied()
130 .ok_or(KernelError::InvalidAddress)?,
131 );
132 }
133 let end = (self.front + self.len) % self.data.capacity();
135 for i in 0..end {
137 BUG_ON!(i + non_wrapping_queue_start_len >= self.data.capacity());
138 self.data.swap(i, i + non_wrapping_queue_start_len);
139 }
140 for i in 0..non_wrapping_queue_start_len {
142 self.data
144 .at_mut(i)
145 .map(|el| *el = unsafe { swap_helper[i].assume_init() });
146 }
147 self.front = 0;
148 }
149 self.data.reserve_total_capacity(new_size)
150 }
151}
152
153#[cfg(test)]
156mod tests {
157 use super::*;
158 use crate::mem::GLOBAL_ALLOCATOR;
159 use core::ops::Range;
160
161 fn alloc_range(length: usize) -> Range<usize> {
162 let alloc_range = std::alloc::Layout::from_size_align(length, align_of::<u128>()).unwrap();
163 let ptr = unsafe { std::alloc::alloc(alloc_range) };
164 ptr as usize..ptr as usize + length
165 }
166
167 fn setup_memory(mem_size: usize) {
168 unsafe {
169 GLOBAL_ALLOCATOR
170 .lock()
171 .add_range(alloc_range(mem_size))
172 .unwrap()
173 };
174 }
175
176 #[test]
177 fn growing_retains_queue_state_without_wrapping() {
178 setup_memory(1000);
179 let mut queue = Queue::<usize, 10>::new();
180 for i in 0..10 {
181 assert_eq!(queue.push_back(i), Ok(()));
182 }
183
184 assert_eq!(queue.grow_capacity(20), Ok(()));
185 for i in 0..10 {
186 assert_eq!(queue.pop_front(), Some(i));
187 }
188 }
189
190 #[test]
191 fn growing_retains_queue_state_with_wrapping() {
192 setup_memory(1000);
193 let mut queue = Queue::<usize, 10>::new();
194 for i in 0..10 {
195 assert_eq!(queue.push_back(i), Ok(()));
196 }
197 assert_eq!(queue.push_back(1), Err(KernelError::OutOfMemory));
199 assert_eq!(queue.len(), 10);
200
201 for i in 0..5 {
203 assert_eq!(queue.pop_front(), Some(i));
204 }
205
206 assert_eq!(*queue.front().unwrap(), 5);
207 assert_eq!(*queue.back().unwrap(), 9);
208 assert_eq!(queue.len(), 5);
209
210 for i in 10..15 {
211 assert_eq!(queue.push_back(i), Ok(()));
212 }
213
214 assert_eq!(queue.len(), 10);
215 assert_eq!(*queue.front().unwrap(), 5);
216 assert_eq!(*queue.back().unwrap(), 14);
217 assert_eq!(queue.grow_capacity(20), Ok(()));
218 for i in 5..15 {
219 assert_eq!(queue.pop_front(), Some(i));
220 }
221 }
222
223 #[test]
224 fn growing_to_smaller_size_has_no_effect() {
225 setup_memory(1000);
226 let mut queue = Queue::<usize, 10>::new();
227 for i in 0..10 {
228 assert_eq!(queue.push_back(i), Ok(()));
229 }
230 assert_eq!(queue.len(), 10);
231 queue.grow_capacity(1).unwrap();
232 assert_eq!(queue.len(), 10);
233 assert_eq!(queue.push_back(1), Err(KernelError::OutOfMemory));
234 }
235
236 #[test]
237 fn growing_multiple_times_consecutively_retains_state() {
238 setup_memory(10000);
239 let mut queue = Queue::<usize, 10>::new();
240 for i in 0..10 {
241 assert_eq!(queue.push_back(i), Ok(()));
242 }
243 assert_eq!(queue.len(), 10);
244
245 for i in 0..5 {
247 assert_eq!(queue.pop_front(), Some(i));
248 }
249 assert_eq!(queue.len(), 5);
250
251 for i in 10..15 {
252 assert_eq!(queue.push_back(i), Ok(()));
253 }
254
255 assert_eq!(queue.len(), 10);
256 assert_eq!(*queue.front().unwrap(), 5);
257 assert_eq!(*queue.back().unwrap(), 14);
258 assert_eq!(queue.grow_capacity(20), Ok(()));
259 assert_eq!(queue.grow_capacity(40), Ok(()));
260 assert_eq!(queue.grow_capacity(100), Ok(()));
261 assert_eq!(queue.grow_capacity(200), Ok(()));
262 for i in 5..15 {
263 assert_eq!(queue.pop_front(), Some(i));
264 }
265 }
266}
267#[cfg(kani)]
271mod verification {
272 use super::*;
273 use core::cmp::max;
274 use std::cmp::min;
275 use std::vec::Vec;
276
277 #[test]
278 fn kani_concrete_playback_growing_retains_queue_state_with_wrapping_7154119071478699851() {
279 let concrete_vals: Vec<Vec<u8>> = vec![
280 vec![128, 134, 1, 0, 0, 0, 0, 0],
282 ];
283 kani::concrete_playback_run(concrete_vals, growing_retains_queue_state_with_wrapping);
284 }
285
286 fn growing_retains_queue_state_with_wrapping() {
289 let mut queue = Queue::<usize, 10>::new();
290 for i in 0..10 {
291 assert_eq!(queue.push_back(i), Ok(()));
292 }
293 assert_eq!(queue.push_back(1), Err(KernelError::OutOfMemory));
295 assert_eq!(queue.len(), 10);
296
297 for i in 0..5 {
299 assert_eq!(queue.pop_front(), Some(i));
300 }
301
302 assert_eq!(*queue.front().unwrap(), 5);
303 assert_eq!(*queue.back().unwrap(), 9);
304 assert_eq!(queue.len(), 5);
305
306 for i in 10..15 {
307 assert_eq!(queue.push_back(i), Ok(()));
308 }
309
310 assert_eq!(queue.len(), 10);
311 assert_eq!(*queue.front().unwrap(), 5);
312 assert_eq!(*queue.back().unwrap(), 14);
313 let new_cap = kani::any();
314 let res = queue.grow_capacity(new_cap);
315
316 if res == Ok(()) && new_cap > 10 {
317 for i in 0..(new_cap - 10) {
318 assert_eq!(queue.push_back(i), Ok(()));
320 }
321 }
322
323 for i in 5..15 {
324 assert_eq!(queue.pop_front(), Some(i));
325 }
326
327 while !queue.is_empty() {
328 let _ = queue.pop_front();
329 }
330
331 if res == Ok(()) && new_cap > 10 {
333 for i in 0..new_cap {
334 assert_eq!(queue.push_back(i), Ok(()));
335 }
336
337 for i in 0..new_cap {
338 assert_eq!(queue.pop_front(), Some(i));
339 }
340 }
341 }
342}
343