async_priority_lock/queue/
boxed.rs1use core::{
6 cell::UnsafeCell,
7 marker::{PhantomData, PhantomPinned},
8 mem::replace,
9 pin::Pin,
10 ptr::NonNull,
11};
12
13#[cfg(not(feature = "std"))]
14extern crate alloc;
15use super::*;
16
17#[cfg(not(feature = "std"))]
18use alloc::boxed::Box;
19#[cfg(feature = "std")]
20use std::boxed::Box;
21
22#[cfg(feature = "const-default")]
23impl<N: BoxQueueNode> const_default::ConstDefault for BoxQueue<N> {
24 const DEFAULT: Self = Self { head: None };
25}
26
27pub struct BoxQueue<N: BoxQueueNode> {
37 head: Option<Pin<Box<N>>>,
38}
39
40pub type SingleLinkBoxQueue<P> = BoxQueue<SingleLinkBoxQueueNode<P>>;
44pub type DualLinkBoxQueue<P> = BoxQueue<DualLinkBoxQueueNode<P>>;
48
49impl<N: BoxQueueNode> BoxQueue<N> {
50 #[inline]
51 fn insert(&mut self, new_node: Pin<Box<N>>) -> <Self as PriorityQueue<N::Data>>::Handle {
52 let ptr = BoxQueueHandle(NonNull::from_ref(&*new_node));
53 if self.head.is_none() {
54 self.head = Some(new_node);
55 return ptr;
56 }
57
58 if new_node
59 .data()
60 .compare_new(&self.head.as_ref().unwrap().data())
64 .is_ge()
65 {
66 self.head.as_ref().unwrap().set_prev(Some(&*new_node));
67 *new_node.next() = self.head.take();
68 self.head = Some(new_node);
69
70 return ptr;
71 }
72
73 let mut curr = self.head.as_ref().unwrap();
74 while let Some(next) = curr.next() {
75 if new_node.data().compare_new(&next.data()).is_ge() {
76 break;
77 }
78
79 curr = next;
80 }
81
82 let next = curr.next().take();
83 if let Some(nxt) = &next {
84 nxt.set_prev(Some(&*new_node));
85 }
86 *new_node.next() = next;
87 new_node.set_prev(Some(&*curr));
88 *curr.next() = Some(new_node);
89
90 ptr
91 }
92}
93
94impl<N: BoxQueueNode> Default for BoxQueue<N> {
95 #[inline]
96 fn default() -> Self {
97 Self {
98 head: Default::default(),
99 }
100 }
101}
102
103impl<N: BoxQueueNode> BoxQueueHandle<N> {
104 #[inline(always)]
105 fn load(&self) -> &N::Data {
106 unsafe { self.0.as_ref() }.data()
107 }
108}
109
110impl<N: BoxQueueNode> From<&Pin<Box<N>>> for SharedBoxQueueHandle<N> {
111 fn from(value: &Pin<Box<N>>) -> Self {
112 Self(BoxQueueHandle(NonNull::from_ref(&value)))
113 }
114}
115
116impl<N: BoxQueueNode> PriorityQueueHandle<N::Data> for BoxQueueHandle<N> {
117 const LOAD_PURE: Option<unsafe fn(&Self) -> &N::Data> = Some(Self::load);
118}
119
120unsafe impl<N: BoxQueueNode> PriorityQueue<N::Data> for BoxQueue<N> {
121 type Handle = BoxQueueHandle<N>;
122 type SharedHandle = SharedBoxQueueHandle<N>;
123
124 fn enqueue(&mut self, data: N::Data) -> Self::Handle {
125 let new_node = Box::pin(N::new(data));
126
127 self.insert(new_node)
128 }
129
130 #[inline(always)]
131 fn get_by_handle(&self, handle: &Self::Handle) -> &N::Data {
132 unsafe { handle.0.as_ref() }.data()
133 }
134
135 #[inline(always)]
136 fn iter_at<'a>(&'a self, after: Option<&Self::Handle>) -> impl Iterator<Item = &'a N::Data>
137 where
138 N::Data: 'a,
139 {
140 if let Some(after) = after {
141 return BoxQueueIterator(after.0.as_ptr().cast_const(), PhantomData);
142 }
143
144 BoxQueueIterator(
145 self.head
146 .as_ref()
147 .map(|x| &raw const **x)
148 .unwrap_or_default(),
149 PhantomData,
150 )
151 }
152
153 #[inline(always)]
154 fn dequeue(
155 &mut self,
156 BoxQueueHandle(ptr): Self::Handle,
157 ) -> (Option<&N::Data>, Option<Self::SharedHandle>) {
158 let ptr = ptr.as_ptr().cast_const();
159 if N::HAS_PREV {
160 let node = unsafe { &*ptr };
161
162 let next = node.next().take();
163 if let Some(nxt) = &next {
164 nxt.set_prev(node.prev());
165 }
166
167 let handle = next.as_ref().map(|x| x.into());
168 if let Some(prev) = node.prev() {
169 *prev.next() = next;
170 return (Some(prev.data()), handle);
171 }
172
173 self.head = next;
175 return (None, handle);
176 }
177
178 if let Some(head) = self.head.as_ref() {
179 if ptr == &**head {
180 self.head = head.next().take();
181 return (None, self.head.as_ref().map(|x| x.into()));
182 }
183 }
184
185 if let Some(mut node) = self.head.as_ref() {
186 while let Some(next) = node.next() {
187 if ptr == &**next {
188 *node.next() = next.next().take();
189
190 return (Some(node.data()), node.next().as_ref().map(|x| x.into()));
191 }
192
193 node = &*next;
194 }
195 }
196
197 (None, None)
198 }
199
200 #[inline]
201 fn is_empty(&self) -> bool {
202 self.head.is_none()
203 }
204
205 fn update_node(&mut self, handle: &Self::Handle, update: impl FnOnce(&mut N::Data) -> bool) {
206 let ptr = handle.0.as_ptr();
207
208 if !update(unsafe { &mut *ptr }.data_mut()) {
209 return;
210 }
211
212 if N::HAS_PREV {
213 let rf = unsafe { &*ptr };
214 if rf
216 .prev()
217 .is_none_or(|x| rf.data().compare(x.data()).is_le())
218 && rf
219 .next()
220 .as_ref()
221 .is_none_or(|nxt| rf.data().compare(nxt.data()).is_ge())
222 {
223 return;
224 }
225
226 let next = rf.next().take();
227
228 if let Some(nxt) = &next {
229 nxt.set_prev(rf.prev());
230 }
231
232 let old_loc = rf.prev().map(|x| x.next()).unwrap_or(&mut self.head);
233
234 rf.set_prev(None);
235 let node = replace(old_loc, next).unwrap();
236
237 self.insert(node);
238 return;
239 }
240
241 if let Some(head) = self.head.as_mut() {
242 if &raw const **head == ptr {
243 if head
244 .next()
245 .as_ref()
246 .is_some_and(|next| head.data().compare(&next.data()).is_le())
247 {
248 let next = head.next().take();
249 let node = replace(&mut self.head, next).unwrap();
250 self.insert(node);
251 }
252
253 return;
254 }
255 }
256
257 if let Some(mut node) = self.head.as_mut() {
258 while let Some(next) = node.next() {
259 if &raw const **next == ptr {
260 if !(next.data().compare(&node.data()).is_le()
262 && next
263 .next()
264 .as_ref()
265 .is_none_or(|next_next| next.data().compare(&next_next.data()).is_ge()))
266 {
267 let to_insert = replace(node.next(), next.next().take()).unwrap();
268
269 self.insert(to_insert);
270 }
271
272 return;
273 }
274
275 node = &mut *next;
276 }
277 }
278
279 unreachable!("handle must be valid")
283 }
284
285 #[inline(always)]
286 fn head_handle(&self) -> Option<Self::SharedHandle> {
287 self.head.as_ref().map(|x| x.into())
288 }
289
290 #[inline]
291 fn get_next_handle(&self, handle: &Self::Handle) -> Option<Self::SharedHandle> {
292 unsafe { handle.0.as_ref() }
293 .next()
294 .as_ref()
295 .map(|x| x.into())
296 }
297}
298
299pub struct BoxQueueHandle<N: BoxQueueNode>(NonNull<N>);
303
304unsafe impl<N: BoxQueueNode> Send for BoxQueueHandle<N> {}
305unsafe impl<N: BoxQueueNode> Sync for BoxQueueHandle<N> {}
306
307struct BoxQueueIterator<'a, N: BoxQueueNode>(*const N, PhantomData<&'a ()>);
308
309pub struct SharedBoxQueueHandle<N: BoxQueueNode>(BoxQueueHandle<N>);
313
314impl<N: BoxQueueNode> AsRef<BoxQueueHandle<N>> for SharedBoxQueueHandle<N> {
315 #[inline(always)]
316 fn as_ref(&self) -> &BoxQueueHandle<N> {
317 &self.0
318 }
319}
320
321impl<'a, N: 'a + BoxQueueNode> Iterator for BoxQueueIterator<'a, N> {
322 type Item = &'a N::Data;
323
324 #[inline(always)]
325 fn next(&mut self) -> Option<Self::Item> {
326 let curr = unsafe { self.0.as_ref()? };
327 let rf = &*curr;
328
329 self.0 = curr
330 .next()
331 .as_ref()
332 .map(|x| &raw const **x)
333 .unwrap_or_default();
334 Some(rf.data())
335 }
336}
337
338#[doc(hidden)]
343pub trait BoxQueueNode {
344 type Data: Priority;
345 const HAS_PREV: bool;
346
347 fn new(data: Self::Data) -> Self;
348 fn data(&self) -> &Self::Data;
349 fn data_mut(self: &mut Self) -> &mut Self::Data;
350
351 fn next<'a>(&self) -> &'a mut Option<Pin<Box<Self>>>;
352
353 fn prev<'a>(&self) -> Option<&'a Self>;
354 fn set_prev(&self, prev: Option<&Self>);
355}
356
357pub struct SingleLinkBoxQueueNode<P: Priority> {
361 data: P,
362 next: UnsafeCell<Option<Pin<Box<Self>>>>,
363 _must_pin: core::marker::PhantomPinned,
364}
365
366unsafe impl<P: Priority + Sync> Sync for SingleLinkBoxQueueNode<P> {}
367
368impl<P: Priority> BoxQueueNode for SingleLinkBoxQueueNode<P> {
369 type Data = P;
370 const HAS_PREV: bool = false;
371
372 #[inline(always)]
373 fn new(data: Self::Data) -> Self {
374 Self {
375 data,
376 next: UnsafeCell::new(None),
377 _must_pin: PhantomPinned,
378 }
379 }
380
381 #[inline(always)]
382 fn next<'a>(&self) -> &'a mut Option<Pin<Box<Self>>> {
383 unsafe { &mut *self.next.get() }
384 }
385
386 #[inline(always)]
387 fn data_mut(&mut self) -> &mut P {
388 &mut self.data
389 }
390
391 #[inline(always)]
392 fn data(&self) -> &Self::Data {
393 &self.data
394 }
395
396 #[inline(always)]
397 fn prev<'a>(&self) -> Option<&'a Self> {
398 unreachable!("single linked box queues do not have prev")
399 }
400
401 #[inline(always)]
402 fn set_prev<'a>(&self, _: Option<&Self>) {}
403}
404
405pub struct DualLinkBoxQueueNode<P: Priority> {
409 data: P,
410 next: UnsafeCell<Option<Pin<Box<Self>>>>,
411 prev: UnsafeCell<Option<NonNull<Self>>>,
412 _must_pin: core::marker::PhantomPinned,
413}
414
415unsafe impl<P: Priority + Send> Send for DualLinkBoxQueueNode<P> {}
416unsafe impl<P: Priority + Sync> Sync for DualLinkBoxQueueNode<P> {}
417
418impl<P: Priority> BoxQueueNode for DualLinkBoxQueueNode<P> {
419 type Data = P;
420 const HAS_PREV: bool = true;
421
422 #[inline(always)]
423 fn new(data: Self::Data) -> Self {
424 Self {
425 data,
426 next: UnsafeCell::new(None),
427 prev: UnsafeCell::new(None),
428 _must_pin: PhantomPinned,
429 }
430 }
431
432 #[inline(always)]
433 fn next<'a>(&self) -> &'a mut Option<Pin<Box<Self>>> {
434 unsafe { &mut *self.next.get() }
435 }
436
437 #[inline(always)]
438 fn data_mut(&mut self) -> &mut Self::Data {
439 &mut self.data
440 }
441
442 #[inline(always)]
443 fn data(&self) -> &Self::Data {
444 &self.data
445 }
446
447 #[inline(always)]
448 fn prev<'a>(&self) -> Option<&'a Self> {
449 let rf = unsafe { &*self.prev.get() };
450
451 rf.map(|x| unsafe { x.as_ref() })
452 }
453
454 fn set_prev(&self, prev: Option<&Self>) {
455 let rf = unsafe { &mut *self.prev.get() };
456
457 *rf = prev.map(|x| NonNull::from_ref(x))
458 }
459}