mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-09-27 12:30:35 +00:00
commit
5b91d6821a
21
CHANGELOG.md
21
CHANGELOG.md
@ -7,8 +7,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v0.2.0] - 2017-11-22
|
||||
|
||||
### Added
|
||||
|
||||
- A single producer single consumer mode to `RingBuffer`.
|
||||
|
||||
- A `truncate` method to `Vec`.
|
||||
|
||||
### Changed
|
||||
|
||||
- [breaking-change] Both `Vec::new` and `RingBuffer::new` no longer require an initial value. The
|
||||
signature of `new` is now `const fn() -> Self`.
|
||||
|
||||
- [breaking-change] The error type of all operations that may fail has changed from `()` to
|
||||
`BufferFullError`.
|
||||
|
||||
- Both `RingBuffer` and `Vec` now support arrays of *any* size for their backup storage.
|
||||
|
||||
## [v0.1.0] - 2017-04-27
|
||||
|
||||
- Initial release
|
||||
|
||||
[Unreleased]: https://github.com/japaric/heapless/compare/v0.1.0...HEAD
|
||||
[Unreleased]: https://github.com/japaric/heapless/compare/v0.2.0...HEAD
|
||||
[v0.2.0]: https://github.com/japaric/heapless/compare/v0.1.0...v0.2.0
|
||||
|
@ -6,9 +6,8 @@ use core::{intrinsics, ptr};
|
||||
|
||||
use untagged_option::UntaggedOption;
|
||||
|
||||
use BufferFullError;
|
||||
|
||||
pub use self::spsc::{Consumer, Producer};
|
||||
use BufferFullError;
|
||||
|
||||
mod spsc;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use core::ptr::{self, Shared};
|
||||
use core::marker::{PhantomData, Unsize};
|
||||
use core::ptr::{self, Shared};
|
||||
|
||||
use BufferFullError;
|
||||
use ring_buffer::RingBuffer;
|
||||
@ -89,6 +89,10 @@ where
|
||||
let buffer: &mut [T] = unsafe { rb.buffer.as_mut() };
|
||||
|
||||
let tail = rb.tail.load_relaxed();
|
||||
// NOTE we could replace this `load_acquire` with a `load_relaxed` and this method would be
|
||||
// sound on most architectures but that change would result in UB according to the C++
|
||||
// memory model, which is what Rust currently uses, so we err on the side of caution and
|
||||
// stick to `load_acquire`. Check issue google#sanitizers#882 for more details.
|
||||
let head = rb.head.load_acquire();
|
||||
let next_tail = (tail + 1) % n;
|
||||
if next_tail != head {
|
||||
|
19
src/vec.rs
19
src/vec.rs
@ -37,6 +37,11 @@ where
|
||||
buffer.len()
|
||||
}
|
||||
|
||||
/// Clears the vector, removing all values.
|
||||
pub fn clear(&mut self) {
|
||||
self.truncate(0);
|
||||
}
|
||||
|
||||
/// Removes the last element from a vector and return it, or `None` if it's empty
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
let buffer: &[T] = unsafe { self.buffer.as_ref() };
|
||||
@ -67,6 +72,20 @@ where
|
||||
Err(BufferFullError)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
|
||||
pub fn truncate(&mut self, len: usize) {
|
||||
unsafe {
|
||||
// drop any extra elements
|
||||
while len < self.len {
|
||||
// decrement len before the drop_in_place(), so a panic on Drop
|
||||
// doesn't re-drop the just-failed value.
|
||||
self.len -= 1;
|
||||
let len = self.len;
|
||||
ptr::drop_in_place(self.get_unchecked_mut(len));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A> Drop for Vec<T, A>
|
||||
|
Loading…
x
Reference in New Issue
Block a user