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