1use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
3use core::{ptr, slice};
4
5pub struct RingBuffer {
18 #[doc(hidden)]
19 pub buf: AtomicPtr<u8>,
20 len: AtomicUsize,
21
22 #[doc(hidden)]
30 pub start: AtomicUsize,
31 #[doc(hidden)]
32 pub end: AtomicUsize,
33}
34
35pub struct Reader<'a>(&'a RingBuffer);
37
38pub struct Writer<'a>(&'a RingBuffer);
40
41impl RingBuffer {
42 pub const fn new() -> Self {
44 Self {
45 buf: AtomicPtr::new(core::ptr::null_mut()),
46 len: AtomicUsize::new(0),
47 start: AtomicUsize::new(0),
48 end: AtomicUsize::new(0),
49 }
50 }
51
52 pub unsafe fn init(&self, buf: *mut u8, len: usize) {
58 self.buf.store(buf, Ordering::Relaxed);
61 self.len.store(len, Ordering::Relaxed);
62 self.start.store(0, Ordering::Relaxed);
63 self.end.store(0, Ordering::Relaxed);
64 }
65
66 pub unsafe fn deinit(&self) {
74 self.buf.store(ptr::null_mut(), Ordering::Relaxed);
77 self.len.store(0, Ordering::Relaxed);
78 self.start.store(0, Ordering::Relaxed);
79 self.end.store(0, Ordering::Relaxed);
80 }
81
82 pub unsafe fn reader(&self) -> Reader<'_> {
89 Reader(self)
90 }
91
92 pub unsafe fn try_reader(&self) -> Option<Reader<'_>> {
98 if self.buf.load(Ordering::Relaxed).is_null() {
99 return None;
100 }
101 Some(Reader(self))
102 }
103
104 pub unsafe fn writer(&self) -> Writer<'_> {
111 Writer(self)
112 }
113
114 pub unsafe fn try_writer(&self) -> Option<Writer<'_>> {
120 if self.buf.load(Ordering::Relaxed).is_null() {
121 return None;
122 }
123 Some(Writer(self))
124 }
125
126 pub fn is_available(&self) -> bool {
128 !self.buf.load(Ordering::Relaxed).is_null() && self.len.load(Ordering::Relaxed) != 0
129 }
130
131 pub fn len(&self) -> usize {
133 self.len.load(Ordering::Relaxed)
134 }
135
136 pub fn available(&self) -> usize {
138 let end = self.end.load(Ordering::Relaxed);
139 let len = self.len.load(Ordering::Relaxed);
140 let start = self.start.load(Ordering::Relaxed);
141 if end >= start {
142 end - start
143 } else {
144 2 * len - start + end
145 }
146 }
147
148 pub fn is_full(&self) -> bool {
150 let len = self.len.load(Ordering::Relaxed);
151 let start = self.start.load(Ordering::Relaxed);
152 let end = self.end.load(Ordering::Relaxed);
153
154 self.wrap(start + len) == end
155 }
156
157 pub fn is_half_full(&self) -> bool {
159 self.available() >= self.len.load(Ordering::Relaxed) / 2
160 }
161
162 pub fn is_empty(&self) -> bool {
164 let start = self.start.load(Ordering::Relaxed);
165 let end = self.end.load(Ordering::Relaxed);
166
167 start == end
168 }
169
170 fn wrap(&self, mut n: usize) -> usize {
171 let len = self.len.load(Ordering::Relaxed);
172
173 if n >= len * 2 {
174 n -= len * 2
175 }
176 n
177 }
178}
179
180impl<'a> Writer<'a> {
181 pub fn push(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> usize {
186 let (p, n) = self.push_buf();
187 let buf = unsafe { slice::from_raw_parts_mut(p, n) };
188 let n = f(buf);
189 self.push_done(n);
190 n
191 }
192
193 pub fn push_one(&mut self, val: u8) -> bool {
197 let n = self.push(|f| match f {
198 [] => 0,
199 [x, ..] => {
200 *x = val;
201 1
202 }
203 });
204 n != 0
205 }
206
207 pub fn push_slice(&mut self) -> &mut [u8] {
211 let (data, len) = self.push_buf();
212 unsafe { slice::from_raw_parts_mut(data, len) }
213 }
214
215 pub fn push_slices(&mut self) -> [&mut [u8]; 2] {
219 let [(d0, l0), (d1, l1)] = self.push_bufs();
220 unsafe { [slice::from_raw_parts_mut(d0, l0), slice::from_raw_parts_mut(d1, l1)] }
221 }
222
223 pub fn push_buf(&mut self) -> (*mut u8, usize) {
235 let mut start = self.0.start.load(Ordering::Acquire);
238 let buf = self.0.buf.load(Ordering::Relaxed);
239 let len = self.0.len.load(Ordering::Relaxed);
240 let mut end = self.0.end.load(Ordering::Relaxed);
241
242 let empty = start == end;
243
244 if start >= len {
245 start -= len
246 }
247 if end >= len {
248 end -= len
249 }
250
251 if start == end && !empty {
252 return (buf, 0);
254 }
255 let n = if start > end { start - end } else { len - end };
256
257 trace!(" ringbuf: push_buf {:?}..{:?}", end, end + n);
258 (unsafe { buf.add(end) }, n)
259 }
260
261 pub fn push_bufs(&mut self) -> [(*mut u8, usize); 2] {
274 let mut start = self.0.start.load(Ordering::Acquire);
276 let buf = self.0.buf.load(Ordering::Relaxed);
277 let len = self.0.len.load(Ordering::Relaxed);
278 let mut end = self.0.end.load(Ordering::Relaxed);
279
280 let empty = start == end;
281
282 if start >= len {
283 start -= len
284 }
285 if end >= len {
286 end -= len
287 }
288
289 if start == end && !empty {
290 return [(buf, 0), (buf, 0)];
292 }
293 let n0 = if start > end { start - end } else { len - end };
294 let n1 = if start <= end { start } else { 0 };
295
296 trace!(" ringbuf: push_bufs [{:?}..{:?}, {:?}..{:?}]", end, end + n0, 0, n1);
297 [(unsafe { buf.add(end) }, n0), (buf, n1)]
298 }
299
300 pub fn push_done(&mut self, n: usize) {
302 trace!(" ringbuf: push {:?}", n);
303 let end = self.0.end.load(Ordering::Relaxed);
304
305 self.0.end.store(self.0.wrap(end + n), Ordering::Release);
310 }
311}
312
313impl<'a> Reader<'a> {
314 pub fn pop(&mut self, f: impl FnOnce(&[u8]) -> usize) -> usize {
319 let (p, n) = self.pop_buf();
320 let buf = unsafe { slice::from_raw_parts(p, n) };
321 let n = f(buf);
322 self.pop_done(n);
323 n
324 }
325
326 pub fn pop_one(&mut self) -> Option<u8> {
330 let mut res = None;
331 self.pop(|f| match f {
332 &[] => 0,
333 &[x, ..] => {
334 res = Some(x);
335 1
336 }
337 });
338 res
339 }
340
341 pub fn pop_slice(&mut self) -> &mut [u8] {
345 let (data, len) = self.pop_buf();
346 unsafe { slice::from_raw_parts_mut(data, len) }
347 }
348
349 pub fn pop_buf(&mut self) -> (*mut u8, usize) {
361 let mut end = self.0.end.load(Ordering::Acquire);
365 let buf = self.0.buf.load(Ordering::Relaxed);
366 let len = self.0.len.load(Ordering::Relaxed);
367 let mut start = self.0.start.load(Ordering::Relaxed);
368
369 if start == end {
370 return (buf, 0);
371 }
372
373 if start >= len {
374 start -= len
375 }
376 if end >= len {
377 end -= len
378 }
379
380 let n = if end > start { end - start } else { len - start };
381
382 trace!(" ringbuf: pop_buf {:?}..{:?}", start, start + n);
383 (unsafe { buf.add(start) }, n)
384 }
385
386 pub fn pop_done(&mut self, n: usize) {
388 trace!(" ringbuf: pop {:?}", n);
389
390 let start = self.0.start.load(Ordering::Relaxed);
391
392 self.0.start.store(self.0.wrap(start + n), Ordering::Release);
399 }
400}
401
402#[cfg(test)]
403mod tests {
404 use super::*;
405
406 #[test]
407 fn push_pop() {
408 let mut b = [0; 4];
409 let rb = RingBuffer::new();
410 unsafe {
411 rb.init(b.as_mut_ptr(), 4);
412
413 assert_eq!(rb.is_empty(), true);
414 assert_eq!(rb.is_half_full(), false);
415 assert_eq!(rb.is_full(), false);
416
417 rb.writer().push(|buf| {
418 assert_eq!(4, buf.len());
419 buf[0] = 1;
420 buf[1] = 2;
421 buf[2] = 3;
422 buf[3] = 4;
423 4
424 });
425
426 assert_eq!(rb.is_empty(), false);
427 assert_eq!(rb.is_half_full(), true);
428 assert_eq!(rb.is_full(), true);
429
430 rb.writer().push(|buf| {
431 assert_eq!(0, buf.len());
433 0
434 });
435
436 assert_eq!(rb.is_empty(), false);
437 assert_eq!(rb.is_half_full(), true);
438 assert_eq!(rb.is_full(), true);
439
440 rb.reader().pop(|buf| {
441 assert_eq!(4, buf.len());
442 assert_eq!(1, buf[0]);
443 1
444 });
445
446 assert_eq!(rb.is_empty(), false);
447 assert_eq!(rb.is_half_full(), true);
448 assert_eq!(rb.is_full(), false);
449
450 rb.reader().pop(|buf| {
451 assert_eq!(3, buf.len());
452 0
453 });
454
455 assert_eq!(rb.is_empty(), false);
456 assert_eq!(rb.is_half_full(), true);
457 assert_eq!(rb.is_full(), false);
458
459 rb.reader().pop(|buf| {
460 assert_eq!(3, buf.len());
461 assert_eq!(2, buf[0]);
462 assert_eq!(3, buf[1]);
463 2
464 });
465 rb.reader().pop(|buf| {
466 assert_eq!(1, buf.len());
467 assert_eq!(4, buf[0]);
468 1
469 });
470
471 assert_eq!(rb.is_empty(), true);
472 assert_eq!(rb.is_half_full(), false);
473 assert_eq!(rb.is_full(), false);
474
475 rb.reader().pop(|buf| {
476 assert_eq!(0, buf.len());
477 0
478 });
479
480 rb.writer().push(|buf| {
481 assert_eq!(4, buf.len());
482 buf[0] = 10;
483 1
484 });
485
486 assert_eq!(rb.is_empty(), false);
487 assert_eq!(rb.is_half_full(), false);
488 assert_eq!(rb.is_full(), false);
489
490 rb.writer().push(|buf| {
491 assert_eq!(3, buf.len());
492 buf[0] = 11;
493 1
494 });
495
496 assert_eq!(rb.is_empty(), false);
497 assert_eq!(rb.is_half_full(), true);
498 assert_eq!(rb.is_full(), false);
499
500 rb.writer().push(|buf| {
501 assert_eq!(2, buf.len());
502 buf[0] = 12;
503 1
504 });
505
506 assert_eq!(rb.is_empty(), false);
507 assert_eq!(rb.is_half_full(), true);
508 assert_eq!(rb.is_full(), false);
509
510 rb.writer().push(|buf| {
511 assert_eq!(1, buf.len());
512 buf[0] = 13;
513 1
514 });
515
516 assert_eq!(rb.is_empty(), false);
517 assert_eq!(rb.is_half_full(), true);
518 assert_eq!(rb.is_full(), true);
519 }
520 }
521
522 #[test]
523 fn zero_len() {
524 let mut b = [0; 0];
525
526 let rb = RingBuffer::new();
527 unsafe {
528 rb.init(b.as_mut_ptr(), b.len());
529
530 assert_eq!(rb.is_empty(), true);
531 assert_eq!(rb.is_half_full(), true);
532 assert_eq!(rb.is_full(), true);
533
534 rb.writer().push(|buf| {
535 assert_eq!(0, buf.len());
536 0
537 });
538
539 rb.reader().pop(|buf| {
540 assert_eq!(0, buf.len());
541 0
542 });
543 }
544 }
545
546 #[test]
547 fn push_slices() {
548 let mut b = [0; 4];
549 let rb = RingBuffer::new();
550 unsafe {
551 rb.init(b.as_mut_ptr(), 4);
552
553 let mut w = rb.writer();
555 let ps = w.push_slices();
556 assert_eq!(4, ps[0].len());
557 assert_eq!(0, ps[1].len());
558 ps[0][0] = 1;
559 ps[0][1] = 2;
560 ps[0][2] = 3;
561 w.push_done(3);
562 drop(w);
563
564 rb.reader().pop(|buf| {
566 assert_eq!(3, buf.len());
567 assert_eq!(1, buf[0]);
568 assert_eq!(2, buf[1]);
569 assert_eq!(3, buf[2]);
570 2
571 });
572
573 let mut w = rb.writer();
575 let ps = w.push_slices();
576 assert_eq!(1, ps[0].len());
577 assert_eq!(2, ps[1].len());
578 ps[0][0] = 4;
579 ps[1][0] = 5;
580 ps[1][1] = 6;
581 w.push_done(3);
582 drop(w);
583
584 let mut w = rb.writer();
586 let ps = w.push_slices();
587 assert_eq!(0, ps[0].len());
588 assert_eq!(0, ps[1].len());
589
590 rb.reader().pop(|buf| {
592 assert_eq!(2, buf.len());
593 assert_eq!(3, buf[0]);
594 assert_eq!(4, buf[1]);
595 2
596 });
597
598 let mut w = rb.writer();
600 let ps = w.push_slices();
601 assert_eq!(2, ps[0].len());
602 assert_eq!(0, ps[1].len());
603 drop(w);
604
605 rb.reader().pop(|buf| {
607 assert_eq!(2, buf.len());
608 assert_eq!(5, buf[0]);
609 assert_eq!(6, buf[1]);
610 2
611 });
612
613 let mut w = rb.writer();
615 let ps = w.push_slices();
616 assert_eq!(2, ps[0].len());
617 assert_eq!(2, ps[1].len());
618 drop(w);
619
620 for _ in 0..10 {
622 let mut w = rb.writer();
624 let ps = w.push_slices();
625 assert_eq!(4, ps[0].len() + ps[1].len());
626 w.push_done(1);
627 drop(w);
628
629 let mut w = rb.writer();
631 let ps = w.push_slices();
632 assert_eq!(3, ps[0].len() + ps[1].len());
633 drop(w);
634
635 rb.reader().pop(|buf| {
637 assert_eq!(1, buf.len());
638 1
639 });
640 }
641 }
642 }
643}