diff --git a/embassy-hal-common/src/atomic_ring_buffer.rs b/embassy-hal-common/src/atomic_ring_buffer.rs index c5e444306..a8a6a2166 100644 --- a/embassy-hal-common/src/atomic_ring_buffer.rs +++ b/embassy-hal-common/src/atomic_ring_buffer.rs @@ -82,10 +82,11 @@ impl RingBuffer { } pub fn is_full(&self) -> bool { + let len = self.len.load(Ordering::Relaxed); let start = self.start.load(Ordering::Relaxed); let end = self.end.load(Ordering::Relaxed); - self.wrap(end + 1) == start + len == 0 || self.wrap(end + 1) == start } pub fn is_empty(&self) -> bool { @@ -134,6 +135,14 @@ impl<'a> Writer<'a> { n != 0 } + /// Get a buffer where data can be pushed to. + /// + /// Equivalent to [`Self::push_buf`] but returns a slice. + pub fn push_slice(&mut self) -> &mut [u8] { + let (data, len) = self.push_buf(); + unsafe { slice::from_raw_parts_mut(data, len) } + } + /// Get a buffer where data can be pushed to. /// /// Write data to the start of the buffer, then call `push_done` with @@ -154,7 +163,7 @@ impl<'a> Writer<'a> { let end = self.0.end.load(Ordering::Relaxed); let n = if start <= end { - len - end - (start == 0) as usize + len - end - (start == 0 && len != 0) as usize } else { start - end - 1 }; @@ -203,6 +212,14 @@ impl<'a> Reader<'a> { res } + /// Get a buffer where data can be popped from. + /// + /// Equivalent to [`Self::pop_buf`] but returns a slice. + pub fn pop_slice(&mut self) -> &mut [u8] { + let (data, len) = self.pop_buf(); + unsafe { slice::from_raw_parts_mut(data, len) } + } + /// Get a buffer where data can be popped from. /// /// Read data from the start of the buffer, then call `pop_done` with @@ -328,4 +345,23 @@ mod tests { assert_eq!(rb.is_full(), true); } } + + #[test] + fn zero_len() { + let rb = RingBuffer::new(); + unsafe { + assert_eq!(rb.is_empty(), true); + assert_eq!(rb.is_full(), true); + + rb.writer().push(|buf| { + assert_eq!(0, buf.len()); + 0 + }); + + rb.reader().pop(|buf| { + assert_eq!(0, buf.len()); + 0 + }); + } + } }