From feaeb533fb5963e9d603ccb5143662b21daed2d8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 19 Dec 2022 01:15:32 +0100 Subject: [PATCH 1/2] hal-common/atomic_ring_buffer: fix crashes when len=0 --- embassy-hal-common/src/atomic_ring_buffer.rs | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/embassy-hal-common/src/atomic_ring_buffer.rs b/embassy-hal-common/src/atomic_ring_buffer.rs index c5e44430..3e90b087 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 { @@ -154,7 +155,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 }; @@ -328,4 +329,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 + }); + } + } } From 5b72410828309bd0d37c8f85c0fb4f88d2a105f8 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 19 Dec 2022 01:16:41 +0100 Subject: [PATCH 2/2] hal-common/atomic_ring_buffer: Add push_slice, pop_slice. --- embassy-hal-common/src/atomic_ring_buffer.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/embassy-hal-common/src/atomic_ring_buffer.rs b/embassy-hal-common/src/atomic_ring_buffer.rs index 3e90b087..a8a6a216 100644 --- a/embassy-hal-common/src/atomic_ring_buffer.rs +++ b/embassy-hal-common/src/atomic_ring_buffer.rs @@ -135,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 @@ -204,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