aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-hal-common/src/atomic_ring_buffer.rs40
1 files changed, 38 insertions, 2 deletions
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 {
82 } 82 }
83 83
84 pub fn is_full(&self) -> bool { 84 pub fn is_full(&self) -> bool {
85 let len = self.len.load(Ordering::Relaxed);
85 let start = self.start.load(Ordering::Relaxed); 86 let start = self.start.load(Ordering::Relaxed);
86 let end = self.end.load(Ordering::Relaxed); 87 let end = self.end.load(Ordering::Relaxed);
87 88
88 self.wrap(end + 1) == start 89 len == 0 || self.wrap(end + 1) == start
89 } 90 }
90 91
91 pub fn is_empty(&self) -> bool { 92 pub fn is_empty(&self) -> bool {
@@ -136,6 +137,14 @@ impl<'a> Writer<'a> {
136 137
137 /// Get a buffer where data can be pushed to. 138 /// Get a buffer where data can be pushed to.
138 /// 139 ///
140 /// Equivalent to [`Self::push_buf`] but returns a slice.
141 pub fn push_slice(&mut self) -> &mut [u8] {
142 let (data, len) = self.push_buf();
143 unsafe { slice::from_raw_parts_mut(data, len) }
144 }
145
146 /// Get a buffer where data can be pushed to.
147 ///
139 /// Write data to the start of the buffer, then call `push_done` with 148 /// Write data to the start of the buffer, then call `push_done` with
140 /// however many bytes you've pushed. 149 /// however many bytes you've pushed.
141 /// 150 ///
@@ -154,7 +163,7 @@ impl<'a> Writer<'a> {
154 let end = self.0.end.load(Ordering::Relaxed); 163 let end = self.0.end.load(Ordering::Relaxed);
155 164
156 let n = if start <= end { 165 let n = if start <= end {
157 len - end - (start == 0) as usize 166 len - end - (start == 0 && len != 0) as usize
158 } else { 167 } else {
159 start - end - 1 168 start - end - 1
160 }; 169 };
@@ -205,6 +214,14 @@ impl<'a> Reader<'a> {
205 214
206 /// Get a buffer where data can be popped from. 215 /// Get a buffer where data can be popped from.
207 /// 216 ///
217 /// Equivalent to [`Self::pop_buf`] but returns a slice.
218 pub fn pop_slice(&mut self) -> &mut [u8] {
219 let (data, len) = self.pop_buf();
220 unsafe { slice::from_raw_parts_mut(data, len) }
221 }
222
223 /// Get a buffer where data can be popped from.
224 ///
208 /// Read data from the start of the buffer, then call `pop_done` with 225 /// Read data from the start of the buffer, then call `pop_done` with
209 /// however many bytes you've processed. 226 /// however many bytes you've processed.
210 /// 227 ///
@@ -328,4 +345,23 @@ mod tests {
328 assert_eq!(rb.is_full(), true); 345 assert_eq!(rb.is_full(), true);
329 } 346 }
330 } 347 }
348
349 #[test]
350 fn zero_len() {
351 let rb = RingBuffer::new();
352 unsafe {
353 assert_eq!(rb.is_empty(), true);
354 assert_eq!(rb.is_full(), true);
355
356 rb.writer().push(|buf| {
357 assert_eq!(0, buf.len());
358 0
359 });
360
361 rb.reader().pop(|buf| {
362 assert_eq!(0, buf.len());
363 0
364 });
365 }
366 }
331} 367}