xref: /aosp_15_r20/external/pigweed/pw_multibuf/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_multibuf:
2
3===========
4pw_multibuf
5===========
6.. pigweed-module::
7   :name: pw_multibuf
8
9Sending or receiving messages via RPC, transfer, or sockets often requires a
10series of intermediate buffers, each requiring their own copy of the data.
11``pw_multibuf`` allows data to be written *once*, eliminating the memory, CPU
12and latency overhead of copying.
13
14-----------------
15How does it work?
16-----------------
17``pw_multibuf`` uses several techniques to minimize copying of data:
18
19- **Header and Footer Reservation**: Lower-level components can reserve space
20  within a buffer for headers and/or footers. This allows headers and footers
21  to be added to user-provided data without moving users' data.
22- **Native Scatter/Gather and Fragmentation Support**: Buffers can refer to
23  multiple separate chunks of memory. Messages can be built up from
24  discontiguous allocations, and users' data can be fragmented across multiple
25  packets.
26- **Divisible Memory Regions**: Incoming buffers can be divided without a copy,
27  allowing incoming data to be freely demultiplexed.
28
29-------------------------------
30What kinds of data is this for?
31-------------------------------
32``pw_multibuf`` is best used in code that wants to read, write, or pass along
33data which are one of the following:
34
35- **Large**: ``pw_multibuf`` is designed to allow breaking up data into
36  multiple chunks. It also supports asynchronous allocation for when there may
37  not be sufficient space for incoming data.
38- **Communications-Oriented**: Data which is being received or sent across
39  sockets, various packets, or shared-memory protocols can benefit from the
40  fragmentation, multiplexing, and header/footer-reservation properties of
41  ``pw_multibuf``.
42- **Copy-Averse**: ``pw_multibuf`` is structured to allow users to pass around
43  and mutate buffers without copying or moving data in-memory. This can be
44  especially useful when working in systems that are latency-sensitive,
45  need to pass large amounts of data, or when memory usage is constrained.
46
47-------------
48API Reference
49-------------
50Most users of ``pw_multibuf`` will start by allocating a ``MultiBuf`` using
51a ``MultiBufAllocator`` class, such as the ``SimpleAllocator``.
52
53``MultiBuf`` s consist of a number of ``Chunk`` s of contiguous memory regions.
54``Chunk`` s can be grown or shrunk which allows ``MultiBuf`` s to be grown or
55shrunk. This allows, for example, lower layers to reserve part of a
56``MultiBuf`` for a header or footer (see ``Chunk`` for more details).
57
58``MultiBuf`` exposes an ``std::byte`` iterator interface as well as a ``Chunk``
59iterator available through the ``Chunks()`` method. It allows extracting a
60``Chunk`` as an RAII-style ``OwnedChunk`` which manages its own lifetime.
61
62.. doxygenclass:: pw::multibuf::Chunk
63   :members:
64
65.. doxygenclass:: pw::multibuf::OwnedChunk
66   :members:
67
68.. doxygenclass:: pw::multibuf::MultiBuf
69   :members:
70
71.. doxygenfunction:: pw::multibuf::FromSpan
72
73.. doxygenclass:: pw::multibuf::MultiBufChunks
74   :members:
75
76.. doxygenclass:: pw::multibuf::MultiBufAllocator
77   :members:
78
79.. doxygenclass:: pw::multibuf::SimpleAllocator
80   :members:
81
82.. doxygenclass:: pw::multibuf::Stream
83   :members:
84
85Test-only features
86==================
87.. doxygenclass:: pw::multibuf::test::SimpleAllocatorForTest
88   :members:
89
90---------------------------
91Allocator Implementors' API
92---------------------------
93Some users will need to directly implement the ``MultiBufAllocator`` interface
94in order to provide allocation out of a particular region, provide particular
95allocation policy, fix Chunks to some size (such as MTU size - header for
96socket implementations), or specify other custom behavior.
97
98These users will also need to understand and implement the following APIs:
99
100.. doxygenclass:: pw::multibuf::ChunkRegionTracker
101   :members:
102
103A simple implementation of a ``ChunkRegionTracker`` is provided, called
104``HeaderChunkRegionTracker``. It stores its ``Chunk`` and region metadata in a
105``Allocator`` allocation alongside the data. The allocation process is
106synchronous, making this class suitable for testing. The allocated region or
107``Chunk`` must not outlive the provided allocator.
108
109.. doxygenclass:: pw::multibuf::HeaderChunkRegionTracker
110   :members:
111
112Another ``ChunkRegionTracker`` specialization is the lightweight
113``SingleChunkRegionTracker``, which does not rely on ``Allocator`` and uses the
114provided memory view to create a single chunk. This is useful when a single
115``Chunk`` is sufficient at no extra overhead. However, the user needs to own
116the provided memory and know when a new ``Chunk`` can be requested.
117
118.. doxygenclass:: pw::multibuf::SingleChunkRegionTracker
119   :members:
120