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