diff options
Diffstat (limited to 'embassy-hal-internal/src/atomic_ring_buffer.rs')
| -rw-r--r-- | embassy-hal-internal/src/atomic_ring_buffer.rs | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/embassy-hal-internal/src/atomic_ring_buffer.rs b/embassy-hal-internal/src/atomic_ring_buffer.rs index ea84925c4..b4f2cec28 100644 --- a/embassy-hal-internal/src/atomic_ring_buffer.rs +++ b/embassy-hal-internal/src/atomic_ring_buffer.rs | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | //! Atomic reusable ringbuffer. | ||
| 1 | use core::slice; | 2 | use core::slice; |
| 2 | use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; | 3 | use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; |
| 3 | 4 | ||
| @@ -14,8 +15,9 @@ use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; | |||
| 14 | /// One concurrent writer and one concurrent reader are supported, even at | 15 | /// One concurrent writer and one concurrent reader are supported, even at |
| 15 | /// different execution priorities (like main and irq). | 16 | /// different execution priorities (like main and irq). |
| 16 | pub struct RingBuffer { | 17 | pub struct RingBuffer { |
| 18 | #[doc(hidden)] | ||
| 17 | pub buf: AtomicPtr<u8>, | 19 | pub buf: AtomicPtr<u8>, |
| 18 | pub len: AtomicUsize, | 20 | len: AtomicUsize, |
| 19 | 21 | ||
| 20 | // start and end wrap at len*2, not at len. | 22 | // start and end wrap at len*2, not at len. |
| 21 | // This allows distinguishing "full" and "empty". | 23 | // This allows distinguishing "full" and "empty". |
| @@ -24,11 +26,16 @@ pub struct RingBuffer { | |||
| 24 | // | 26 | // |
| 25 | // This avoids having to consider the ringbuffer "full" at len-1 instead of len. | 27 | // This avoids having to consider the ringbuffer "full" at len-1 instead of len. |
| 26 | // The usual solution is adding a "full" flag, but that can't be made atomic | 28 | // The usual solution is adding a "full" flag, but that can't be made atomic |
| 29 | #[doc(hidden)] | ||
| 27 | pub start: AtomicUsize, | 30 | pub start: AtomicUsize, |
| 31 | #[doc(hidden)] | ||
| 28 | pub end: AtomicUsize, | 32 | pub end: AtomicUsize, |
| 29 | } | 33 | } |
| 30 | 34 | ||
| 35 | /// A type which can only read from a ring buffer. | ||
| 31 | pub struct Reader<'a>(&'a RingBuffer); | 36 | pub struct Reader<'a>(&'a RingBuffer); |
| 37 | |||
| 38 | /// A type which can only write to a ring buffer. | ||
| 32 | pub struct Writer<'a>(&'a RingBuffer); | 39 | pub struct Writer<'a>(&'a RingBuffer); |
| 33 | 40 | ||
| 34 | impl RingBuffer { | 41 | impl RingBuffer { |
| @@ -89,10 +96,12 @@ impl RingBuffer { | |||
| 89 | Writer(self) | 96 | Writer(self) |
| 90 | } | 97 | } |
| 91 | 98 | ||
| 99 | /// Return length of buffer. | ||
| 92 | pub fn len(&self) -> usize { | 100 | pub fn len(&self) -> usize { |
| 93 | self.len.load(Ordering::Relaxed) | 101 | self.len.load(Ordering::Relaxed) |
| 94 | } | 102 | } |
| 95 | 103 | ||
| 104 | /// Check if buffer is full. | ||
| 96 | pub fn is_full(&self) -> bool { | 105 | pub fn is_full(&self) -> bool { |
| 97 | let len = self.len.load(Ordering::Relaxed); | 106 | let len = self.len.load(Ordering::Relaxed); |
| 98 | let start = self.start.load(Ordering::Relaxed); | 107 | let start = self.start.load(Ordering::Relaxed); |
| @@ -101,6 +110,7 @@ impl RingBuffer { | |||
| 101 | self.wrap(start + len) == end | 110 | self.wrap(start + len) == end |
| 102 | } | 111 | } |
| 103 | 112 | ||
| 113 | /// Check if buffer is empty. | ||
| 104 | pub fn is_empty(&self) -> bool { | 114 | pub fn is_empty(&self) -> bool { |
| 105 | let start = self.start.load(Ordering::Relaxed); | 115 | let start = self.start.load(Ordering::Relaxed); |
| 106 | let end = self.end.load(Ordering::Relaxed); | 116 | let end = self.end.load(Ordering::Relaxed); |
| @@ -238,6 +248,7 @@ impl<'a> Writer<'a> { | |||
| 238 | [(unsafe { buf.add(end) }, n0), (buf, n1)] | 248 | [(unsafe { buf.add(end) }, n0), (buf, n1)] |
| 239 | } | 249 | } |
| 240 | 250 | ||
| 251 | /// Mark n bytes as written and advance the write index. | ||
| 241 | pub fn push_done(&mut self, n: usize) { | 252 | pub fn push_done(&mut self, n: usize) { |
| 242 | trace!(" ringbuf: push {:?}", n); | 253 | trace!(" ringbuf: push {:?}", n); |
| 243 | let end = self.0.end.load(Ordering::Relaxed); | 254 | let end = self.0.end.load(Ordering::Relaxed); |
| @@ -323,6 +334,7 @@ impl<'a> Reader<'a> { | |||
| 323 | (unsafe { buf.add(start) }, n) | 334 | (unsafe { buf.add(start) }, n) |
| 324 | } | 335 | } |
| 325 | 336 | ||
| 337 | /// Mark n bytes as read and allow advance the read index. | ||
| 326 | pub fn pop_done(&mut self, n: usize) { | 338 | pub fn pop_done(&mut self, n: usize) { |
| 327 | trace!(" ringbuf: pop {:?}", n); | 339 | trace!(" ringbuf: pop {:?}", n); |
| 328 | 340 | ||
