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