Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function for queue space left #57

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## Unreleased

- Added `space_left` function for queue

# 2.0.2 07-05-24

- Added check for too big items that won't ever fit in flash so it returns a good clear error.
Expand Down
6 changes: 3 additions & 3 deletions fuzz/fuzz_targets/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {

for op in ops.ops.into_iter() {
#[cfg(fuzzing_repro)]
eprintln!("{}", flash.print_items());
eprintln!("{}", block_on(flash.print_items()));
#[cfg(fuzzing_repro)]
eprintln!("{:?}", cache);
#[cfg(fuzzing_repro)]
Expand Down Expand Up @@ -120,14 +120,14 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
)) {
Ok(Some(check_item)) if check_item == value => {
#[cfg(fuzzing_repro)]
eprintln!("Early shutoff when storing {item:?}! (but it still stored fully). Originated from:\n{_backtrace:#}");
eprintln!("Early shutoff when storing key: {key}, value: {value:?}! (but it still stored fully). Originated from:\n{_backtrace:#}");
// Even though we got a shutoff, it still managed to store well
map.insert(key, value);
}
_ => {
// Could not fetch the item we stored...
#[cfg(fuzzing_repro)]
eprintln!("Early shutoff when storing {item:?}! Originated from:\n{_backtrace:#}");
eprintln!("Early shutoff when storing key: {key}, value: {value:?}! Originated from:\n{_backtrace:#}");
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions fuzz/fuzz_targets/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ fn fuzz(ops: Input, mut cache: impl CacheImpl + Debug) {

for mut op in ops.ops.into_iter() {
#[cfg(fuzzing_repro)]
eprintln!("{}", flash.print_items());
eprintln!("{}", block_on(flash.print_items()));
#[cfg(fuzzing_repro)]
eprintln!("{:?}", cache);
#[cfg(fuzzing_repro)]
Expand Down Expand Up @@ -128,7 +128,7 @@ fn fuzz(ops: Input, mut cache: impl CacheImpl + Debug) {
backtrace: _backtrace,
}) => {
// We need to check if it managed to write
if let Some(true) = flash.get_item_presence(address) {
if let Some(true) = block_on(flash.get_item_presence(address)) {
#[cfg(fuzzing_repro)]
eprintln!("Early shutoff when pushing {val:?}! (but it still stored fully). Originated from:\n{_backtrace:#}");
order.push_back(val);
Expand Down Expand Up @@ -172,7 +172,7 @@ fn fuzz(ops: Input, mut cache: impl CacheImpl + Debug) {
"Early shutoff when popping (single)! Originated from:\n{_backtrace:#}"
);

if !matches!(flash.get_item_presence(address), Some(true)) {
if !matches!(block_on(flash.get_item_presence(address)), Some(true)) {
// The item is no longer readable here
order.pop_front();
}
Expand Down Expand Up @@ -276,7 +276,10 @@ fn fuzz(ops: Input, mut cache: impl CacheImpl + Debug) {
"Early shutoff when popping iterator entry! Originated from:\n{_backtrace:#}"
);

if !matches!(flash.get_item_presence(address), Some(true)) {
if !matches!(
block_on(flash.get_item_presence(address)),
Some(true)
) {
// The item is no longer readable here
order.remove(i - popped_items).unwrap();
}
Expand Down
8 changes: 8 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ pub async fn erase_all<S: NorFlash>(
})
}

/// Get the minimal overhead size per stored item for the given flash type.
///
/// The associated data of each item is additionally padded to a full flash word size, but that's not part of this number.
/// This means the full item length is `returned number + (data length).next_multiple_of(S::WORD_SIZE)`.
pub const fn item_overhead_size<S: NorFlash>() -> u32 {
item::ItemHeader::data_address::<S>(0)
}

// Type representing buffer aligned to 4 byte boundary.
#[repr(align(4))]
pub(crate) struct AlignedBuf<const SIZE: usize>(pub(crate) [u8; SIZE]);
Expand Down
36 changes: 18 additions & 18 deletions src/mock_flash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,11 @@ impl<const PAGES: usize, const BYTES_PER_WORD: usize, const PAGE_WORDS: usize>
self.current_stats
}

#[cfg(feature = "_test")]
#[cfg(any(test, feature = "_test"))]
/// Print all items in flash to the returned string
pub fn print_items(&mut self) -> String {
pub async fn print_items(&mut self) -> String {
use crate::cache::NoCache;
use crate::NorFlashExt;
use futures::executor::block_on;
use std::fmt::Write;

let mut buf = [0; 1024 * 16];
Expand All @@ -132,12 +131,14 @@ impl<const PAGES: usize, const BYTES_PER_WORD: usize, const PAGE_WORDS: usize>
writeln!(
s,
" Page {page_index} ({}):",
match block_on(crate::get_page_state(
match crate::get_page_state(
self,
Self::FULL_FLASH_RANGE,
&mut NoCache::new(),
page_index
)) {
)
.await
{
Ok(value) => format!("{value:?}"),
Err(e) => format!("Error ({e:?})"),
}
Expand All @@ -151,13 +152,13 @@ impl<const PAGES: usize, const BYTES_PER_WORD: usize, const PAGE_WORDS: usize>
- Self::WORD_SIZE as u32;

let mut it = crate::item::ItemHeaderIter::new(page_data_start, page_data_end);
while let (Some(header), item_address) =
block_on(it.traverse(self, |_, _| false)).unwrap()
while let (Some(header), item_address) = it.traverse(self, |_, _| false).await.unwrap()
{
let next_item_address = header.next_item_address::<Self>(item_address);
let maybe_item =
block_on(header.read_item(self, &mut buf, item_address, page_data_end))
.unwrap();
let maybe_item = header
.read_item(self, &mut buf, item_address, page_data_end)
.await
.unwrap();
writeln!(
s,
" Item {maybe_item:?} at {item_address}..{next_item_address}"
Expand All @@ -169,15 +170,14 @@ impl<const PAGES: usize, const BYTES_PER_WORD: usize, const PAGE_WORDS: usize>
s
}

#[cfg(feature = "_test")]
#[cfg(any(test, feature = "_test"))]
/// Get the presence of the item at the given address.
///
/// - If some, the item is there.
/// - If true, the item is present and fine.
/// - If false, the item is corrupt or erased.
pub fn get_item_presence(&mut self, target_item_address: u32) -> Option<bool> {
pub async fn get_item_presence(&mut self, target_item_address: u32) -> Option<bool> {
use crate::NorFlashExt;
use futures::executor::block_on;

if !Self::FULL_FLASH_RANGE.contains(&target_item_address) {
return None;
Expand All @@ -197,14 +197,14 @@ impl<const PAGES: usize, const BYTES_PER_WORD: usize, const PAGE_WORDS: usize>

let mut found_item = None;
let mut it = crate::item::ItemHeaderIter::new(page_data_start, page_data_end);
while let (Some(header), item_address) = block_on(it.traverse(self, |_, _| false)).unwrap()
{
while let (Some(header), item_address) = it.traverse(self, |_, _| false).await.unwrap() {
let next_item_address = header.next_item_address::<Self>(item_address);

if (item_address..next_item_address).contains(&target_item_address) {
let maybe_item =
block_on(header.read_item(self, &mut buf, item_address, page_data_end))
.unwrap();
let maybe_item = header
.read_item(self, &mut buf, item_address, page_data_end)
.await
.unwrap();

match maybe_item {
crate::item::MaybeItem::Corrupted(_, _)
Expand Down
Loading
Loading