1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_ring_buffer: 2*61c4878aSAndroid Build Coastguard Worker 3*61c4878aSAndroid Build Coastguard Worker============== 4*61c4878aSAndroid Build Coastguard Workerpw_ring_buffer 5*61c4878aSAndroid Build Coastguard Worker============== 6*61c4878aSAndroid Build Coastguard WorkerThe ``pw_ring_buffer`` module will eventually provide several ring buffer 7*61c4878aSAndroid Build Coastguard Workerimplementations, each with different tradeoffs. 8*61c4878aSAndroid Build Coastguard Worker 9*61c4878aSAndroid Build Coastguard WorkerThis documentation is incomplete :) 10*61c4878aSAndroid Build Coastguard Worker 11*61c4878aSAndroid Build Coastguard Worker----------------------- 12*61c4878aSAndroid Build Coastguard WorkerPrefixedEntryRingBuffer 13*61c4878aSAndroid Build Coastguard Worker----------------------- 14*61c4878aSAndroid Build Coastguard Worker:cpp:class:`pw::ring_buffer::PrefixedEntryRingBuffer` is a circular buffer for 15*61c4878aSAndroid Build Coastguard Workerarbitrary length data entries with an optional user-defined preamble byte. It 16*61c4878aSAndroid Build Coastguard Workersupports multiple independent readers. 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard WorkerIterator 19*61c4878aSAndroid Build Coastguard Worker======== 20*61c4878aSAndroid Build Coastguard WorkerIn crash contexts, it may be useful to scan through a ring buffer that may 21*61c4878aSAndroid Build Coastguard Workerhave a mix of valid (yet to be read), stale (read), and invalid entries. The 22*61c4878aSAndroid Build Coastguard Worker``PrefixedEntryRingBufferMulti::iterator`` class can be used to walk through 23*61c4878aSAndroid Build Coastguard Workerentries in the provided buffer. 24*61c4878aSAndroid Build Coastguard Worker 25*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 26*61c4878aSAndroid Build Coastguard Worker 27*61c4878aSAndroid Build Coastguard Worker // A test string to push into the buffer. 28*61c4878aSAndroid Build Coastguard Worker constexpr char kExampleEntry[] = "Example!"; 29*61c4878aSAndroid Build Coastguard Worker 30*61c4878aSAndroid Build Coastguard Worker // Setting up buffers and attaching a reader. 31*61c4878aSAndroid Build Coastguard Worker std::byte buffer[1024]; 32*61c4878aSAndroid Build Coastguard Worker std::byte read_buffer[256]; 33*61c4878aSAndroid Build Coastguard Worker PrefixedEntryRingBuffer ring_buffer; 34*61c4878aSAndroid Build Coastguard Worker PrefixedEntryRingBuffer::Reader reader; 35*61c4878aSAndroid Build Coastguard Worker ring_buffer.SetBuffer(buffer); 36*61c4878aSAndroid Build Coastguard Worker ring_buffer.AttachReader(reader); 37*61c4878aSAndroid Build Coastguard Worker 38*61c4878aSAndroid Build Coastguard Worker // Insert some entries and process some entries. 39*61c4878aSAndroid Build Coastguard Worker ring_buffer.PushBack(kExampleEntry); 40*61c4878aSAndroid Build Coastguard Worker ring_buffer.PushBack(kExampleEntry); 41*61c4878aSAndroid Build Coastguard Worker reader.PopFront(); 42*61c4878aSAndroid Build Coastguard Worker 43*61c4878aSAndroid Build Coastguard Worker // !! A function causes a crash before we've read out all entries. 44*61c4878aSAndroid Build Coastguard Worker FunctionThatCrashes(); 45*61c4878aSAndroid Build Coastguard Worker 46*61c4878aSAndroid Build Coastguard Worker // ... Crash Context ... 47*61c4878aSAndroid Build Coastguard Worker 48*61c4878aSAndroid Build Coastguard Worker // You can use a range-based for-loop to walk through all entries. 49*61c4878aSAndroid Build Coastguard Worker for (auto entry : ring_buffer) { 50*61c4878aSAndroid Build Coastguard Worker PW_LOG_WARN("Read entry of size: %u", 51*61c4878aSAndroid Build Coastguard Worker static_cast<unsigned>(entry.buffer.size())); 52*61c4878aSAndroid Build Coastguard Worker } 53*61c4878aSAndroid Build Coastguard Worker 54*61c4878aSAndroid Build Coastguard WorkerIn cases where a crash has caused the ring buffer to have corrupted data, the 55*61c4878aSAndroid Build Coastguard Workeriterator will progress until it sees the corrupted section and instead move to 56*61c4878aSAndroid Build Coastguard Worker``iterator::end()``. The ``iterator::status()`` function returns a 57*61c4878aSAndroid Build Coastguard Worker:cpp:class:`pw::Status` indicating the reason the iterator reached it's end. 58*61c4878aSAndroid Build Coastguard Worker 59*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp 60*61c4878aSAndroid Build Coastguard Worker 61*61c4878aSAndroid Build Coastguard Worker // ... Crash Context ... 62*61c4878aSAndroid Build Coastguard Worker 63*61c4878aSAndroid Build Coastguard Worker using iterator = PrefixedEntryRingBufferMulti::iterator; 64*61c4878aSAndroid Build Coastguard Worker 65*61c4878aSAndroid Build Coastguard Worker // Hold the iterator outside any loops to inspect it later. 66*61c4878aSAndroid Build Coastguard Worker iterator it = ring_buffer.begin(); 67*61c4878aSAndroid Build Coastguard Worker for (; it != it.end(); ++it) { 68*61c4878aSAndroid Build Coastguard Worker PW_LOG_WARN("Read entry of size: %u", 69*61c4878aSAndroid Build Coastguard Worker static_cast<unsigned>(it->buffer.size())); 70*61c4878aSAndroid Build Coastguard Worker } 71*61c4878aSAndroid Build Coastguard Worker 72*61c4878aSAndroid Build Coastguard Worker // Warn if there was a failure during iteration. 73*61c4878aSAndroid Build Coastguard Worker if (!it.status().ok()) { 74*61c4878aSAndroid Build Coastguard Worker PW_LOG_WARN("Iterator failed to read some entries!"); 75*61c4878aSAndroid Build Coastguard Worker } 76*61c4878aSAndroid Build Coastguard Worker 77*61c4878aSAndroid Build Coastguard WorkerData corruption 78*61c4878aSAndroid Build Coastguard Worker=============== 79*61c4878aSAndroid Build Coastguard Worker``PrefixedEntryRingBufferMulti`` offers a circular ring buffer for arbitrary 80*61c4878aSAndroid Build Coastguard Workerlength data entries. Some metadata bytes are added at the beginning of each 81*61c4878aSAndroid Build Coastguard Workerentry to delimit the size of the entry. Unlike the iterator, the methods in 82*61c4878aSAndroid Build Coastguard Worker``PrefixedEntryRingBufferMulti`` require that data in the buffer is not corrupt. 83*61c4878aSAndroid Build Coastguard WorkerWhen these methods encounter data corruption, there is no generic way to 84*61c4878aSAndroid Build Coastguard Workerrecover, and thus, the application crashes. Data corruption is indicative of 85*61c4878aSAndroid Build Coastguard Workerother issues. 86