@@ -305,10 +305,95 @@ impl<T, const N: usize> Queue<T, N> {
305
305
self . inner_dequeue_unchecked ( )
306
306
}
307
307
308
- /// Splits a queue into producer and consumer endpoints
308
+ /// Splits a queue into producer and consumer endpoints.
309
+ ///
310
+ /// # Examples
311
+ ///
312
+ /// ```
313
+ /// use core::cell::RefCell;
314
+ /// use critical_section::Mutex;
315
+ /// use heapless::spsc::{Queue, Producer};
316
+ ///
317
+ /// static PRODUCER: Mutex<RefCell<Option<Producer<'static, (), 4>>>> =
318
+ /// Mutex::new(RefCell::new(None));
319
+ ///
320
+ /// fn main() {
321
+ /// let mut consumer = {
322
+ /// let (p, c) = {
323
+ /// static mut Q: Queue<(), 4> = Queue::new();
324
+ /// // SAFETY: Mutable access to `Q` is allowed exclusively in this scope
325
+ /// // and `main` is only called once.
326
+ /// unsafe { Q.split() }
327
+ /// };
328
+ ///
329
+ /// critical_section::with(move |cs| {
330
+ /// let mut producer = PRODUCER.borrow_ref_mut(cs);
331
+ /// *producer = Some(p);
332
+ /// });
333
+ ///
334
+ /// c
335
+ /// };
336
+ /// }
337
+ ///
338
+ /// fn interrupt() {
339
+ /// let mut producer = {
340
+ /// static mut P: Option<Producer<'static, (), 4>> = None;
341
+ /// // SAFETY: Mutable access to `P` is allowed exclusively in this scope
342
+ /// // and `interrupt` cannot be called directly or preempt itself.
343
+ /// unsafe { &mut P }
344
+ /// }.get_or_insert_with(|| {
345
+ /// critical_section::with(|cs| {
346
+ /// PRODUCER.borrow_ref_mut(cs).take().unwrap()
347
+ /// })
348
+ /// });
349
+ /// }
350
+ /// ```
351
+ #[ cfg( not( feature = "nightly" ) ) ]
309
352
pub fn split ( & mut self ) -> ( Producer < ' _ , T , N > , Consumer < ' _ , T , N > ) {
310
353
( Producer { rb : self } , Consumer { rb : self } )
311
354
}
355
+
356
+ /// Splits a queue into producer and consumer endpoints.
357
+ ///
358
+ /// # Examples
359
+ ///
360
+ /// ```
361
+ /// #![feature(const_mut_refs)]
362
+ ///
363
+ /// use core::cell::RefCell;
364
+ ///
365
+ /// use critical_section::Mutex;
366
+ /// use heapless::spsc::{Queue, Producer, Consumer};
367
+ ///
368
+ /// static PC: Mutex<RefCell<(Option<Producer<'static, (), 4>>, Option<Consumer<'static, (), 4>>)>> = {
369
+ /// static mut Q: Queue<(), 4> = Queue::new();
370
+ /// let (p, c) = unsafe { Q.split() };
371
+ /// Mutex::new(RefCell::new((Some(p), Some(c))))
372
+ /// };
373
+ ///
374
+ /// fn main() {
375
+ /// let mut consumer = critical_section::with(|cs| {
376
+ /// (*PC.borrow_ref_mut(cs)).1.take().unwrap()
377
+ /// });
378
+ /// }
379
+ ///
380
+ /// fn interrupt() {
381
+ /// let mut producer = {
382
+ /// static mut P: Option<Producer<'static, (), 4>> = None;
383
+ /// // SAFETY: Mutable access to `P` is allowed exclusively in this scope
384
+ /// // and `interrupt` cannot be called directly or preempt itself.
385
+ /// unsafe { &mut P }
386
+ /// }.get_or_insert_with(|| {
387
+ /// critical_section::with(|cs| {
388
+ /// (*PC.borrow_ref_mut(cs)).0.take().unwrap()
389
+ /// })
390
+ /// });
391
+ /// }
392
+ /// ```
393
+ #[ cfg( feature = "nightly" ) ]
394
+ pub const fn split ( & mut self ) -> ( Producer < ' _ , T , N > , Consumer < ' _ , T , N > ) {
395
+ ( Producer { rb : self } , Consumer { rb : self } )
396
+ }
312
397
}
313
398
314
399
impl < T , const N : usize > Default for Queue < T , N > {
@@ -632,7 +717,36 @@ impl<'a, T, const N: usize> Producer<'a, T, N> {
632
717
mod tests {
633
718
use std:: hash:: { Hash , Hasher } ;
634
719
635
- use crate :: spsc:: Queue ;
720
+ use super :: Queue ;
721
+
722
+ #[ cfg( feature = "nightly" ) ]
723
+ #[ test]
724
+ fn const_split ( ) {
725
+ use critical_section:: Mutex ;
726
+ use std:: cell:: RefCell ;
727
+
728
+ static PC : Mutex <
729
+ RefCell < (
730
+ Option < Producer < ' static , ( ) , 4 > > ,
731
+ Option < Consumer < ' static , ( ) , 4 > > ,
732
+ ) > ,
733
+ > = {
734
+ static mut Q : Queue < ( ) , 4 > = Queue :: new ( ) ;
735
+ let ( p, c) = unsafe { Q . split ( ) } ;
736
+ Mutex :: new ( RefCell :: new ( ( Some ( p) , Some ( c) ) ) )
737
+ } ;
738
+
739
+ let ( producer, consumer) = critical_section:: with ( |cs| {
740
+ let mut pc = PC . borrow_ref_mut ( cs) ;
741
+ ( pc. 0 . take ( ) . unwrap ( ) , pc. 1 . take ( ) . unwrap ( ) )
742
+ } ) ;
743
+
744
+ let mut producer: Producer < ' static , ( ) , 4 > = producer;
745
+ let mut consumer: Consumer < ' static , ( ) , 4 > = consumer;
746
+
747
+ assert_eq ! ( producer. enqueue( ( ) ) , Ok ( ( ) ) ) ;
748
+ assert_eq ! ( consumer. dequeue( ) , Some ( ( ) ) ) ;
749
+ }
636
750
637
751
#[ test]
638
752
fn full ( ) {
0 commit comments