aboutsummaryrefslogtreecommitdiff
path: root/pw_multibuf/docs.rst
blob: e19f8e7ce9a57b424c5c4c6f16dec2a305178c21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
.. _module-pw_multibuf:

===========
pw_multibuf
===========
.. pigweed-module::
   :name: pw_multibuf
   :tagline: A buffer API optimized for zero-copy messaging
   :status: unstable
   :languages: C++17

Sending or receiving messages via RPC, transfer, or sockets often requires a
series of intermediate buffers, each requiring their own copy of the data.
``pw_multibuf`` allows data to be written *once*, eliminating the memory, CPU
and latency overhead of copying.

-----------------
How does it work?
-----------------
``pw_multibuf`` uses several techniques to minimize copying of data:

- **Header and Footer Reservation**: Lower-level components can reserve space
  within a buffer for headers and/or footers. This allows headers and footers
  to be added to user-provided data without moving users' data.
- **Native Scatter/Gather and Fragmentation Support**: Buffers can refer to
  multiple separate chunks of memory. Messages can be built up from
  discontiguous allocations, and users' data can be fragmented across multiple
  packets.
- **Divisible Memory Regions**: Incoming buffers can be divided without a copy,
  allowing incoming data to be freely demultiplexed.

-------------------------------
What kinds of data is this for?
-------------------------------
``pw_multibuf`` is best used in code that wants to read, write, or pass along
data which are one of the following:

- **Large**: ``pw_multibuf`` is designed to allow breaking up data into
  multiple chunks. It also supports asynchronous allocation for when there may
  not be sufficient space for incoming data.
- **Communications-Oriented**: Data which is being received or sent across
  sockets, various packets, or shared-memory protocols can benefit from the
  fragmentation, multiplexing, and header/footer-reservation properties of
  ``pw_multibuf``.
- **Copy-Averse**: ``pw_multibuf`` is structured to allow users to pass around
  and mutate buffers without copying or moving data in-memory. This can be
  especially useful when working in systems that are latency-sensitive,
  need to pass large amounts of data, or when memory usage is constrained.

-------------
API Reference
-------------
Most users of ``pw_multibuf`` will start by allocating a ``MultiBuf`` using
a ``MultiBufAllocator`` class.

``MultiBuf`` s consist of a number of ``Chunk`` s of contiguous memory.
These ``Chunk`` s can be grown, shrunk, modified, or extracted from the
``MultiBuf``. ``MultiBuf`` exposes an ``std::byte`` iterator interface as well
as a ``Chunk`` iterator available through the ``Chunks()`` method.

An RAII-style ``OwnedChunk`` is also provided, and manages the lifetime of
``Chunk`` s which are not currently stored inside of a ``MultiBuf``.

.. doxygenclass:: pw::multibuf::Chunk
   :members:

.. doxygenclass:: pw::multibuf::OwnedChunk
   :members:

.. doxygenclass:: pw::multibuf::MultiBuf
   :members:

.. doxygenclass:: pw::multibuf::MultiBufAllocator
   :members:

---------------------------
Allocator Implementors' API
---------------------------
Some users will need to directly implement the ``MultiBufAllocator`` interface
in order to provide allocation out of a particular region, provide particular
allocation policy, fix Chunks to some size (such as MTU size - header for
socket implementations), or specify other custom behavior.

These users will also need to understand and implement the following APIs:

.. doxygenclass:: pw::multibuf::ChunkRegionTracker
   :members: