1extern crate alloc;
4
5use bincode::{Decode, Encode};
6use std::fmt;
7
8use cu29_traits::CopperListTuple;
9use serde_derive::Serialize;
10use std::fmt::Display;
11use std::iter::{Chain, Rev};
12use std::slice::{Iter as SliceIter, IterMut as SliceIterMut};
13
14const MAX_TASKS: usize = 512;
15
16#[derive(Debug, Encode, Decode, PartialEq, Clone, Copy)]
19pub struct CopperLiskMask {
20 #[allow(dead_code)]
21 mask: [u128; MAX_TASKS / 128 + 1],
22}
23
24#[derive(Debug, Encode, Decode, Serialize, PartialEq, Copy, Clone)]
26pub enum CopperListState {
27 Free,
28 Initialized,
29 Processing,
30 DoneProcessing,
31 BeingSerialized,
32}
33
34impl Display for CopperListState {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 CopperListState::Free => write!(f, "Free"),
38 CopperListState::Initialized => write!(f, "Initialized"),
39 CopperListState::Processing => write!(f, "Processing"),
40 CopperListState::DoneProcessing => write!(f, "DoneProcessing"),
41 CopperListState::BeingSerialized => write!(f, "BeingSerialized"),
42 }
43 }
44}
45
46#[derive(Debug, Encode, Decode)]
47pub struct CopperList<P: CopperListTuple> {
48 pub id: u32,
49 state: CopperListState,
50 pub msgs: P, }
52
53impl<P: CopperListTuple> CopperList<P> {
54 pub fn new(id: u32, msgs: P) -> Self {
56 CopperList {
57 id,
58 state: CopperListState::Initialized,
59 msgs,
60 }
61 }
62
63 pub fn change_state(&mut self, new_state: CopperListState) {
64 self.state = new_state; }
66
67 pub fn get_state(&self) -> CopperListState {
68 self.state
69 }
70}
71
72pub struct CuListsManager<P: CopperListTuple, const N: usize> {
76 data: Box<[CopperList<P>; N]>,
77 length: usize,
78 insertion_index: usize,
79 current_cl_id: u32,
80}
81
82impl<P: CopperListTuple + fmt::Debug, const N: usize> fmt::Debug for CuListsManager<P, N> {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 f.debug_struct("CuListsManager")
85 .field("data", &self.data)
86 .field("length", &self.length)
87 .field("insertion_index", &self.insertion_index)
88 .finish()
90 }
91}
92
93pub type Iter<'a, T> = Chain<Rev<SliceIter<'a, T>>, Rev<SliceIter<'a, T>>>;
94pub type IterMut<'a, T> = Chain<Rev<SliceIterMut<'a, T>>, Rev<SliceIterMut<'a, T>>>;
95pub type AscIter<'a, T> = Chain<SliceIter<'a, T>, SliceIter<'a, T>>;
96pub type AscIterMut<'a, T> = Chain<SliceIterMut<'a, T>, SliceIterMut<'a, T>>;
97
98impl<P: CopperListTuple, const N: usize> Default for CuListsManager<P, N> {
99 fn default() -> Self {
100 Self::new()
101 }
102}
103
104impl<P: CopperListTuple, const N: usize> CuListsManager<P, N> {
105 pub fn new() -> Self {
106 let data = unsafe {
107 let layout = std::alloc::Layout::new::<[CopperList<P>; N]>();
108 let ptr = std::alloc::alloc_zeroed(layout) as *mut [CopperList<P>; N];
109 Box::from_raw(ptr)
110 };
111 CuListsManager {
112 data,
113 length: 0,
114 insertion_index: 0,
115 current_cl_id: 0,
116 }
117 }
118
119 #[inline]
122 pub fn len(&self) -> usize {
123 self.length
124 }
125
126 #[inline]
129 pub fn is_empty(&self) -> bool {
130 self.length == 0
131 }
132
133 #[inline]
136 pub fn is_full(&self) -> bool {
137 N == self.len()
138 }
139
140 #[inline]
143 pub fn clear(&mut self) {
144 self.insertion_index = 0;
145 self.length = 0;
146 }
147
148 #[inline]
149 pub fn create(&mut self) -> Option<&mut CopperList<P>> {
150 if self.is_full() {
151 return None;
152 }
153 let result = &mut self.data[self.insertion_index];
154 self.insertion_index = (self.insertion_index + 1) % N;
155 self.length += 1;
156
157 result.id = self.current_cl_id;
159 self.current_cl_id += 1;
160
161 Some(result)
162 }
163
164 #[inline]
166 pub fn peek(&self) -> Option<&CopperList<P>> {
167 if self.length == 0 {
168 return None;
169 }
170 let index = if self.insertion_index == 0 {
171 N - 1
172 } else {
173 self.insertion_index - 1
174 };
175 Some(&self.data[index])
176 }
177
178 #[inline]
179 #[allow(dead_code)]
180 fn drop_last(&mut self) {
181 if self.length == 0 {
182 return;
183 }
184 if self.insertion_index == 0 {
185 self.insertion_index = N - 1;
186 } else {
187 self.insertion_index -= 1;
188 }
189 self.length -= 1;
190 }
191
192 #[inline]
193 pub fn pop(&mut self) -> Option<&mut CopperList<P>> {
194 if self.length == 0 {
195 return None;
196 }
197 if self.insertion_index == 0 {
198 self.insertion_index = N - 1;
199 } else {
200 self.insertion_index -= 1;
201 }
202 self.length -= 1;
203 Some(&mut self.data[self.insertion_index])
204 }
205
206 #[inline]
211 pub fn iter(&self) -> Iter<CopperList<P>> {
212 let (a, b) = self.data[0..self.length].split_at(self.insertion_index);
213 a.iter().rev().chain(b.iter().rev())
214 }
215
216 #[inline]
221 pub fn iter_mut(&mut self) -> IterMut<CopperList<P>> {
222 let (a, b) = self.data.split_at_mut(self.insertion_index);
223 a.iter_mut().rev().chain(b.iter_mut().rev())
224 }
225
226 #[inline]
231 pub fn asc_iter(&self) -> AscIter<CopperList<P>> {
232 let (a, b) = self.data.split_at(self.insertion_index);
233 b.iter().chain(a.iter())
234 }
235
236 #[inline]
241 pub fn asc_iter_mut(&mut self) -> AscIterMut<CopperList<P>> {
242 let (a, b) = self.data.split_at_mut(self.insertion_index);
243 b.iter_mut().chain(a.iter_mut())
244 }
245}
246
247#[cfg(test)]
248mod tests {
249 use super::*;
250
251 #[test]
252 fn empty_queue() {
253 let q = CuListsManager::<i32, 5>::new();
254
255 assert!(q.is_empty());
256 assert!(q.iter().next().is_none());
257 }
258
259 #[test]
260 fn partially_full_queue() {
261 let mut q = CuListsManager::<i32, 5>::new();
262 q.create().unwrap().msgs = 1;
263 q.create().unwrap().msgs = 2;
264 q.create().unwrap().msgs = 3;
265
266 assert!(!q.is_empty());
267 assert_eq!(q.len(), 3);
268
269 let res: Vec<i32> = q.iter().map(|x| x.msgs).collect();
270 assert_eq!(res, [3, 2, 1]);
271 }
272
273 #[test]
274 fn full_queue() {
275 let mut q = CuListsManager::<i32, 5>::new();
276 q.create().unwrap().msgs = 1;
277 q.create().unwrap().msgs = 2;
278 q.create().unwrap().msgs = 3;
279 q.create().unwrap().msgs = 4;
280 q.create().unwrap().msgs = 5;
281 assert_eq!(q.len(), 5);
282
283 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
284 assert_eq!(res, [5, 4, 3, 2, 1]);
285 }
286
287 #[test]
288 fn over_full_queue() {
289 let mut q = CuListsManager::<i32, 5>::new();
290 q.create().unwrap().msgs = 1;
291 q.create().unwrap().msgs = 2;
292 q.create().unwrap().msgs = 3;
293 q.create().unwrap().msgs = 4;
294 q.create().unwrap().msgs = 5;
295 assert!(q.create().is_none());
296 assert_eq!(q.len(), 5);
297
298 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
299 assert_eq!(res, [5, 4, 3, 2, 1]);
300 }
301
302 #[test]
303 fn clear() {
304 let mut q = CuListsManager::<i32, 5>::new();
305 q.create().unwrap().msgs = 1;
306 q.create().unwrap().msgs = 2;
307 q.create().unwrap().msgs = 3;
308 q.create().unwrap().msgs = 4;
309 q.create().unwrap().msgs = 5;
310 assert!(q.create().is_none());
311 assert_eq!(q.len(), 5);
312
313 q.clear();
314
315 assert_eq!(q.len(), 0);
316 assert!(q.iter().next().is_none());
317
318 q.create().unwrap().msgs = 1;
319 q.create().unwrap().msgs = 2;
320 q.create().unwrap().msgs = 3;
321
322 assert_eq!(q.len(), 3);
323
324 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
325 assert_eq!(res, [3, 2, 1]);
326 }
327
328 #[test]
329 fn mutable_iterator() {
330 let mut q = CuListsManager::<i32, 5>::new();
331 q.create().unwrap().msgs = 1;
332 q.create().unwrap().msgs = 2;
333 q.create().unwrap().msgs = 3;
334 q.create().unwrap().msgs = 4;
335 q.create().unwrap().msgs = 5;
336
337 for x in q.iter_mut() {
338 x.msgs *= 2;
339 }
340
341 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
342 assert_eq!(res, [10, 8, 6, 4, 2]);
343 }
344
345 #[test]
346 fn zero_sized() {
347 let mut q = CuListsManager::<(), 5>::new();
348 *q.create().unwrap() = CopperList::new(0, ());
349 *q.create().unwrap() = CopperList::new(1, ());
350 *q.create().unwrap() = CopperList::new(2, ());
351
352 assert_eq!(q.len(), 3);
353
354 let mut iter = q.iter();
355 iter.next().unwrap();
356 iter.next().unwrap();
357 iter.next().unwrap();
358 assert!(iter.next().is_none());
359 }
360
361 #[test]
362 fn be_sure_we_wont_stackoverflow_at_init() {
363 let _ = CuListsManager::<[u8; 10_000_000], 3>::new();
364 }
365
366 #[test]
367 fn test_drop_last() {
368 let mut q = CuListsManager::<i32, 5>::new();
369 q.create().unwrap().msgs = 1;
370 q.create().unwrap().msgs = 2;
371 q.create().unwrap().msgs = 3;
372 q.create().unwrap().msgs = 4;
373 q.create().unwrap().msgs = 5;
374 assert_eq!(q.len(), 5);
375
376 q.drop_last();
377 assert_eq!(q.len(), 4);
378
379 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
380 assert_eq!(res, [4, 3, 2, 1]);
381 }
382
383 #[test]
384 fn test_pop() {
385 let mut q = CuListsManager::<i32, 5>::new();
386 q.create().unwrap().msgs = 1;
387 q.create().unwrap().msgs = 2;
388 q.create().unwrap().msgs = 3;
389 q.create().unwrap().msgs = 4;
390 q.create().unwrap().msgs = 5;
391 assert_eq!(q.len(), 5);
392
393 let last = q.pop().unwrap();
394 assert_eq!(last.msgs, 5);
395 assert_eq!(q.len(), 4);
396
397 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
398 assert_eq!(res, [4, 3, 2, 1]);
399 }
400
401 #[test]
402 fn test_peek() {
403 let mut q = CuListsManager::<i32, 5>::new();
404 q.create().unwrap().msgs = 1;
405 q.create().unwrap().msgs = 2;
406 q.create().unwrap().msgs = 3;
407 q.create().unwrap().msgs = 4;
408 q.create().unwrap().msgs = 5;
409 assert_eq!(q.len(), 5);
410
411 let last = q.peek().unwrap();
412 assert_eq!(last.msgs, 5);
413 assert_eq!(q.len(), 5);
414
415 let res: Vec<_> = q.iter().map(|x| x.msgs).collect();
416 assert_eq!(res, [5, 4, 3, 2, 1]);
417 }
418}