pw_ring_buffer#

Pigweed AI summary: The pw_ring_buffer module provides different ring buffer implementations with varying tradeoffs, but the documentation is incomplete. The PrefixedEntryRingBufferMulti::iterator class can be used to scan through a ring buffer in crash contexts, and the iterator will progress until it sees corrupted data and move to iterator::end(). The PrefixedEntryRingBufferMulti offers a circular ring buffer for arbitrary length data entries, but its methods require that data in the buffer is not corrupt. The module has dependencies on pw_span and

The pw_ring_buffer module will eventually provide several ring buffer implementations, each with different tradeoffs.

This documentation is incomplete :)

Compatibility#

Pigweed AI summary: This section titled "Compatibility" lists C++14 as the only compatibility requirement.

  • C++14

Iterator#

Pigweed AI summary: The PrefixedEntryRingBufferMulti::iterator class can be used to scan through a ring buffer that may have a mix of valid, stale, and invalid entries in crash contexts. The iterator will progress until it sees the corrupted section and instead move to iterator::end(). The iterator::status() function returns a pw::Status indicating the reason the iterator reached its end. A range-based for-loop can be used to walk through all entries, and if there was a failure during iteration, the iterator will

In crash contexts, it may be useful to scan through a ring buffer that may have a mix of valid (yet to be read), stale (read), and invalid entries. The PrefixedEntryRingBufferMulti::iterator class can be used to walk through entries in the provided buffer.

// A test string to push into the buffer.
constexpr char kExampleEntry[] = "Example!";

// Setting up buffers and attaching a reader.
std::byte buffer[1024];
std::byte read_buffer[256];
PrefixedEntryRingBuffer ring_buffer;
PrefixedEntryRingBuffer::Reader reader;
ring_buffer.SetBuffer(buffer);
ring_buffer.AttachReader(reader);

// Insert some entries and process some entries.
ring_buffer.PushBack(kExampleEntry);
ring_buffer.PushBack(kExampleEntry);
reader.PopFront();

// !! A function causes a crash before we've read out all entries.
FunctionThatCrashes();

// ... Crash Context ...

// You can use a range-based for-loop to walk through all entries.
for (auto entry : ring_buffer) {
  PW_LOG_WARN("Read entry of size: %u",
              static_cast<unsigned>(entry.buffer.size()));
}

In cases where a crash has caused the ring buffer to have corrupted data, the iterator will progress until it sees the corrupted section and instead move to iterator::end(). The iterator::status() function returns a pw::Status indicating the reason the iterator reached it’s end.

// ... Crash Context ...

using iterator = PrefixedEntryRingBufferMulti::iterator;

// Hold the iterator outside any loops to inspect it later.
iterator it = ring_buffer.begin();
for (; it != it.end(); ++it) {
  PW_LOG_WARN("Read entry of size: %u",
             static_cast<unsigned>(it->buffer.size()));
}

// Warn if there was a failure during iteration.
if (!it.status().ok()) {
  PW_LOG_WARN("Iterator failed to read some entries!");
}

Data corruption#

Pigweed AI summary: The article discusses data corruption in the PrefixedEntryRingBufferMulti, which is a circular ring buffer for arbitrary length data entries. The buffer adds metadata bytes at the beginning of each entry to delimit the size of the entry. However, the methods in PrefixedEntryRingBufferMulti require that data in the buffer is not corrupt. If data corruption occurs, there is no generic way to recover, and the application crashes. Data corruption is indicative of other issues.

PrefixedEntryRingBufferMulti offers a circular ring buffer for arbitrary length data entries. Some metadata bytes are added at the beginning of each entry to delimit the size of the entry. Unlike the iterator, the methods in PrefixedEntryRingBufferMulti require that data in the buffer is not corrupt. When these methods encounter data corruption, there is no generic way to recover, and thus, the application crashes. Data corruption is indicative of other issues.

Dependencies#

Pigweed AI summary: This paragraph lists the dependencies required for a project, including "pw_span" and "pw_containers" (which is only necessary for testing purposes).

  • pw_span

  • pw_containers - for tests only