xref: /aosp_15_r20/external/pigweed/pw_allocator/guide.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_allocator-guides:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker======
4*61c4878aSAndroid Build Coastguard WorkerGuides
5*61c4878aSAndroid Build Coastguard Worker======
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module-subpage::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_allocator
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard Worker.. _module-pw_allocator-get-started:
10*61c4878aSAndroid Build Coastguard Worker
11*61c4878aSAndroid Build Coastguard Worker-----------
12*61c4878aSAndroid Build Coastguard WorkerGet started
13*61c4878aSAndroid Build Coastguard Worker-----------
14*61c4878aSAndroid Build Coastguard Worker.. tab-set::
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: Bazel
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker      Add ``@pigweed//pw_allocator`` to the ``deps`` list in your Bazel target:
19*61c4878aSAndroid Build Coastguard Worker
20*61c4878aSAndroid Build Coastguard Worker      .. code-block::
21*61c4878aSAndroid Build Coastguard Worker
22*61c4878aSAndroid Build Coastguard Worker         cc_library("...") {
23*61c4878aSAndroid Build Coastguard Worker           # ...
24*61c4878aSAndroid Build Coastguard Worker           deps = [
25*61c4878aSAndroid Build Coastguard Worker             # ...
26*61c4878aSAndroid Build Coastguard Worker             "@pigweed//pw_allocator",
27*61c4878aSAndroid Build Coastguard Worker             # ...
28*61c4878aSAndroid Build Coastguard Worker           ]
29*61c4878aSAndroid Build Coastguard Worker         }
30*61c4878aSAndroid Build Coastguard Worker
31*61c4878aSAndroid Build Coastguard Worker      For a narrower dependency, depend on subtargets, e.g.
32*61c4878aSAndroid Build Coastguard Worker      ``@pigweed//pw_allocator:tracking_allocator``.
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard Worker      This assumes ``@pigweed`` is the name you pulled Pigweed into your Bazel
35*61c4878aSAndroid Build Coastguard Worker      ``WORKSPACE`` as.
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker      This assumes that your Bazel ``WORKSPACE`` has a `repository`_ named
38*61c4878aSAndroid Build Coastguard Worker      ``@pigweed`` that points to the upstream Pigweed repository.
39*61c4878aSAndroid Build Coastguard Worker
40*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: GN
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker      Add ``dir_pw_allocator`` to the ``deps`` list in your build target:
43*61c4878aSAndroid Build Coastguard Worker
44*61c4878aSAndroid Build Coastguard Worker      .. code-block::
45*61c4878aSAndroid Build Coastguard Worker
46*61c4878aSAndroid Build Coastguard Worker         pw_executable("...") {
47*61c4878aSAndroid Build Coastguard Worker           # ...
48*61c4878aSAndroid Build Coastguard Worker           deps = [
49*61c4878aSAndroid Build Coastguard Worker             # ...
50*61c4878aSAndroid Build Coastguard Worker             dir_pw_allocator,
51*61c4878aSAndroid Build Coastguard Worker             # ...
52*61c4878aSAndroid Build Coastguard Worker           ]
53*61c4878aSAndroid Build Coastguard Worker         }
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker      For a narrower dependency, depend on subtargets, e.g.
56*61c4878aSAndroid Build Coastguard Worker      ``"$dir_pw_allocator:tracking_allocator"``.
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard Worker      If the build target is a dependency of other targets and includes
59*61c4878aSAndroid Build Coastguard Worker      allocators in its public interface, e.g. its header file, use
60*61c4878aSAndroid Build Coastguard Worker      ``public_deps`` instead of ``deps``.
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Worker   .. tab-item:: CMake
63*61c4878aSAndroid Build Coastguard Worker
64*61c4878aSAndroid Build Coastguard Worker      Add ``pw_allocator`` to your ``pw_add_library`` or similar CMake target:
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard Worker      .. code-block::
67*61c4878aSAndroid Build Coastguard Worker
68*61c4878aSAndroid Build Coastguard Worker         pw_add_library(my_library STATIC
69*61c4878aSAndroid Build Coastguard Worker           HEADERS
70*61c4878aSAndroid Build Coastguard Worker             ...
71*61c4878aSAndroid Build Coastguard Worker           PRIVATE_DEPS
72*61c4878aSAndroid Build Coastguard Worker             # ...
73*61c4878aSAndroid Build Coastguard Worker             pw_allocator
74*61c4878aSAndroid Build Coastguard Worker             # ...
75*61c4878aSAndroid Build Coastguard Worker         )
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker      For a narrower dependency, depend on subtargets, e.g.
78*61c4878aSAndroid Build Coastguard Worker      ``pw_allocator.tracking_allocator``, etc.
79*61c4878aSAndroid Build Coastguard Worker
80*61c4878aSAndroid Build Coastguard Worker      If the build target is a dependency of other targets and includes
81*61c4878aSAndroid Build Coastguard Worker      allocators in its public interface, e.g. its header file, use
82*61c4878aSAndroid Build Coastguard Worker      ``PUBLIC_DEPS`` instead of ``PRIVATE_DEPS``.
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard Worker.. _module-pw_allocator-module-configuration:
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker--------------------
87*61c4878aSAndroid Build Coastguard WorkerModule configuration
88*61c4878aSAndroid Build Coastguard Worker--------------------
89*61c4878aSAndroid Build Coastguard WorkerThis module has configuration options that globally affect the behavior of
90*61c4878aSAndroid Build Coastguard Worker``pw_allocator`` via compile-time configuration of this module, see the
91*61c4878aSAndroid Build Coastguard Worker:ref:`module documentation <module-structure-compile-time-configuration>` for
92*61c4878aSAndroid Build Coastguard Workermore details.
93*61c4878aSAndroid Build Coastguard Worker
94*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_ALLOCATOR_STRICT_VALIDATION
95*61c4878aSAndroid Build Coastguard Worker.. doxygendefine:: PW_ALLOCATOR_BLOCK_POISON_INTERVAL
96*61c4878aSAndroid Build Coastguard Worker
97*61c4878aSAndroid Build Coastguard Worker-----------------
98*61c4878aSAndroid Build Coastguard WorkerInject allocators
99*61c4878aSAndroid Build Coastguard Worker-----------------
100*61c4878aSAndroid Build Coastguard WorkerRoutines that need to allocate memory dynamically should do so using the generic
101*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-allocator` interface. By using dependency
102*61c4878aSAndroid Build Coastguard Workerinjection, memory users can be kept decoupled from the details of how memory is
103*61c4878aSAndroid Build Coastguard Workerprovided. This yields the most flexibility for modifying or replacing the
104*61c4878aSAndroid Build Coastguard Workerspecific allocators.
105*61c4878aSAndroid Build Coastguard Worker
106*61c4878aSAndroid Build Coastguard WorkerUse the ``Allocator`` interface
107*61c4878aSAndroid Build Coastguard Worker===============================
108*61c4878aSAndroid Build Coastguard WorkerWrite or refactor your memory-using routines to take
109*61c4878aSAndroid Build Coastguard Workera pointer or reference to such an object and use the ``Allocate``,
110*61c4878aSAndroid Build Coastguard Worker``Deallocate``, ``Reallocate``, and ``Resize`` methods to manage memory. For
111*61c4878aSAndroid Build Coastguard Workerexample:
112*61c4878aSAndroid Build Coastguard Worker
113*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/basic.cc
114*61c4878aSAndroid Build Coastguard Worker   :language: cpp
115*61c4878aSAndroid Build Coastguard Worker   :linenos:
116*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-basic-allocate]
117*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-basic-allocate]
118*61c4878aSAndroid Build Coastguard Worker
119*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/basic.cc
120*61c4878aSAndroid Build Coastguard Worker   :language: cpp
121*61c4878aSAndroid Build Coastguard Worker   :linenos:
122*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-basic-deallocate]
123*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-basic-deallocate]
124*61c4878aSAndroid Build Coastguard Worker
125*61c4878aSAndroid Build Coastguard WorkerTo invoke methods or objects that inject allocators now requires an allocator to
126*61c4878aSAndroid Build Coastguard Workerhave been constructed. The exact location where allocators should be
127*61c4878aSAndroid Build Coastguard Workerinstantiated will vary from project to project, but it's likely to be early in a
128*61c4878aSAndroid Build Coastguard Workerprogram's lifecycle and in a device-specific location of the source tree.
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard WorkerFor initial testing on :ref:`target-host`, a simple allocator such as
131*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-libc_allocator` can be used. This allocator is
132*61c4878aSAndroid Build Coastguard Workertrivally constructed and simply wraps ``malloc`` and ``free``.
133*61c4878aSAndroid Build Coastguard Worker
134*61c4878aSAndroid Build Coastguard WorkerUse New and Delete
135*61c4878aSAndroid Build Coastguard Worker==================
136*61c4878aSAndroid Build Coastguard WorkerIn addition to managing raw memory, an ``Allocator`` can also be used to create
137*61c4878aSAndroid Build Coastguard Workerand destroy objects:
138*61c4878aSAndroid Build Coastguard Worker
139*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/basic.cc
140*61c4878aSAndroid Build Coastguard Worker   :language: cpp
141*61c4878aSAndroid Build Coastguard Worker   :linenos:
142*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-basic-new_delete]
143*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-basic-new_delete]
144*61c4878aSAndroid Build Coastguard Worker
145*61c4878aSAndroid Build Coastguard WorkerUse UniquePtr<T>
146*61c4878aSAndroid Build Coastguard Worker================
147*61c4878aSAndroid Build Coastguard WorkerWhere possible, using `RAII`_ is a recommended approach for making memory
148*61c4878aSAndroid Build Coastguard Workermanagement easier and less error-prone.
149*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-unique_ptr` is a smart pointer that makes
150*61c4878aSAndroid Build Coastguard Workerallocating and deallocating memory more transparent:
151*61c4878aSAndroid Build Coastguard Worker
152*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/basic.cc
153*61c4878aSAndroid Build Coastguard Worker   :language: cpp
154*61c4878aSAndroid Build Coastguard Worker   :linenos:
155*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-basic-make_unique]
156*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-basic-make_unique]
157*61c4878aSAndroid Build Coastguard Worker
158*61c4878aSAndroid Build Coastguard WorkerDetermine an allocation's Layout
159*61c4878aSAndroid Build Coastguard Worker================================
160*61c4878aSAndroid Build Coastguard WorkerSeveral of the :ref:`module-pw_allocator-api-allocator` methods take a parameter
161*61c4878aSAndroid Build Coastguard Workerof the :ref:`module-pw_allocator-api-layout` type. This type combines the size
162*61c4878aSAndroid Build Coastguard Workerand alignment requirements of an allocation. It can be constructed directly, or
163*61c4878aSAndroid Build Coastguard Workerif allocating memory for a specific type, by using a templated static method:
164*61c4878aSAndroid Build Coastguard Worker
165*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/block_allocator.cc
166*61c4878aSAndroid Build Coastguard Worker   :language: cpp
167*61c4878aSAndroid Build Coastguard Worker   :linenos:
168*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-block_allocator-layout_of]
169*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-block_allocator-layout_of]
170*61c4878aSAndroid Build Coastguard Worker
171*61c4878aSAndroid Build Coastguard WorkerAs stated above, you should generally try to keep allocator implementation
172*61c4878aSAndroid Build Coastguard Workerdetails abstracted behind the :ref:`module-pw_allocator-api-allocator`
173*61c4878aSAndroid Build Coastguard Workerinterface. One exception to this guidance is when integrating allocators into
174*61c4878aSAndroid Build Coastguard Workerexisting code that assumes ``malloc`` and ``free`` semantics. Notably, ``free``
175*61c4878aSAndroid Build Coastguard Workerdoes not take any parameters beyond a pointer describing the memory to be freed.
176*61c4878aSAndroid Build Coastguard Worker
177*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/block_allocator.cc
178*61c4878aSAndroid Build Coastguard Worker   :language: cpp
179*61c4878aSAndroid Build Coastguard Worker   :linenos:
180*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-block_allocator-malloc_free]
181*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-block_allocator-malloc_free]
182*61c4878aSAndroid Build Coastguard Worker
183*61c4878aSAndroid Build Coastguard Worker.. _module-pw_allocator-use-standard-library-containers:
184*61c4878aSAndroid Build Coastguard Worker
185*61c4878aSAndroid Build Coastguard WorkerUse standard library containers
186*61c4878aSAndroid Build Coastguard Worker===============================
187*61c4878aSAndroid Build Coastguard WorkerAll of C++'s standard library containers are `AllocatorAwareContainers`_, with
188*61c4878aSAndroid Build Coastguard Workerthe exception of ``std::array``. These types include a template parameter used
189*61c4878aSAndroid Build Coastguard Workerto specify an allocator type, and a constructor which takes a reference to an
190*61c4878aSAndroid Build Coastguard Workerobject of this type.
191*61c4878aSAndroid Build Coastguard Worker
192*61c4878aSAndroid Build Coastguard WorkerWhile there are
193*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-design-differences-with-polymorphic-allocators`, an
194*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-allocator` can be used with these containers by
195*61c4878aSAndroid Build Coastguard Workerwrapping them with a PMR adapter type,
196*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-pmr_allocator`:
197*61c4878aSAndroid Build Coastguard Worker
198*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/pmr.cc
199*61c4878aSAndroid Build Coastguard Worker   :language: cpp
200*61c4878aSAndroid Build Coastguard Worker   :linenos:
201*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-pmr]
202*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-pmr]
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard Worker.. Warning::
205*61c4878aSAndroid Build Coastguard Worker   Some of the standard library containers may add a significant amount of
206*61c4878aSAndroid Build Coastguard Worker   additional code size and/or memory overhead. In particular, implementations
207*61c4878aSAndroid Build Coastguard Worker   of ``std::deque`` are known to preallocate significant memory in order to
208*61c4878aSAndroid Build Coastguard Worker   meet its complexity requirements, e.g. O(1) insertion at the front of the
209*61c4878aSAndroid Build Coastguard Worker   deque.
210*61c4878aSAndroid Build Coastguard Worker
211*61c4878aSAndroid Build Coastguard Worker.. Warning::
212*61c4878aSAndroid Build Coastguard Worker   The standard library containers expect their allocators to throw an exception
213*61c4878aSAndroid Build Coastguard Worker   on allocation failure, and do not check for failure themselves. If
214*61c4878aSAndroid Build Coastguard Worker   exceptions are disabled, :ref:`module-pw_allocator-api-pmr_allocator`
215*61c4878aSAndroid Build Coastguard Worker   instead **asserts** that allocation succeeded. Care must be taken in this
216*61c4878aSAndroid Build Coastguard Worker   case to ensure that memory is not exhausted.
217*61c4878aSAndroid Build Coastguard Worker
218*61c4878aSAndroid Build Coastguard Worker--------------------------
219*61c4878aSAndroid Build Coastguard WorkerChoose the right allocator
220*61c4878aSAndroid Build Coastguard Worker--------------------------
221*61c4878aSAndroid Build Coastguard WorkerOnce one or more routines are using allocators, you can consider how best to
222*61c4878aSAndroid Build Coastguard Workerimplement memory allocation for each particular scenario.
223*61c4878aSAndroid Build Coastguard Worker
224*61c4878aSAndroid Build Coastguard Worker.. TODO(b/378549332): Add a decision tree for selecting an allocator.
225*61c4878aSAndroid Build Coastguard Worker
226*61c4878aSAndroid Build Coastguard WorkerConcrete allocator implementations
227*61c4878aSAndroid Build Coastguard Worker==================================
228*61c4878aSAndroid Build Coastguard WorkerThis module provides several allocator implementations. The following is an
229*61c4878aSAndroid Build Coastguard Workeroverview. Consult the :ref:`module-pw_allocator-api` for additional details.
230*61c4878aSAndroid Build Coastguard Worker
231*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-libc_allocator`: Uses ``malloc``, ``realloc``,
232*61c4878aSAndroid Build Coastguard Worker  and ``free``. This should only be used if the ``libc`` in use provides those
233*61c4878aSAndroid Build Coastguard Worker  functions. This allocator is a stateless singleton that may be referenced
234*61c4878aSAndroid Build Coastguard Worker  using ``GetLibCAllocator()``.
235*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-null_allocator`: Always fails. This may be
236*61c4878aSAndroid Build Coastguard Worker  useful if allocations should be disallowed under specific circumstances.
237*61c4878aSAndroid Build Coastguard Worker  This allocator is a stateless singleton that may be referenced using
238*61c4878aSAndroid Build Coastguard Worker  ``GetNullAllocator()``.
239*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-bump_allocator`: Allocates objects out of a
240*61c4878aSAndroid Build Coastguard Worker  region of memory and only frees them all at once when the allocator is
241*61c4878aSAndroid Build Coastguard Worker  destroyed.
242*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-buddy_allocator`: Allocates objects out of a
243*61c4878aSAndroid Build Coastguard Worker  blocks with sizes that are powers of two. Blocks are split evenly for smaller
244*61c4878aSAndroid Build Coastguard Worker  allocations and merged on free.
245*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-block_allocator`: Tracks memory using
246*61c4878aSAndroid Build Coastguard Worker  :ref:`module-pw_allocator-api-block`. Derived types use specific strategies
247*61c4878aSAndroid Build Coastguard Worker  for how to choose a block to use to satisfy a request. See also
248*61c4878aSAndroid Build Coastguard Worker  :ref:`module-pw_allocator-design-block`. Derived types include:
249*61c4878aSAndroid Build Coastguard Worker
250*61c4878aSAndroid Build Coastguard Worker  - :ref:`module-pw_allocator-api-first_fit_allocator`: Chooses the first
251*61c4878aSAndroid Build Coastguard Worker    block that's large enough to satisfy a request. This strategy is very fast,
252*61c4878aSAndroid Build Coastguard Worker    but may increase fragmentation.
253*61c4878aSAndroid Build Coastguard Worker  - :ref:`module-pw_allocator-api-best_fit_allocator`: Chooses the
254*61c4878aSAndroid Build Coastguard Worker    smallest block that's large enough to satisfy a request. This strategy
255*61c4878aSAndroid Build Coastguard Worker    maximizes the avilable space for large allocations, but may increase
256*61c4878aSAndroid Build Coastguard Worker    fragmentation and is slower.
257*61c4878aSAndroid Build Coastguard Worker  - :ref:`module-pw_allocator-api-worst_fit_allocator`: Chooses the
258*61c4878aSAndroid Build Coastguard Worker    largest block if it's large enough to satisfy a request. This strategy
259*61c4878aSAndroid Build Coastguard Worker    minimizes the amount of memory in unusably small blocks, but is slower.
260*61c4878aSAndroid Build Coastguard Worker  - :ref:`module-pw_allocator-api-bucket_block_allocator`: Sorts and stores
261*61c4878aSAndroid Build Coastguard Worker    each free blocks in a :ref:`module-pw_allocator-api-bucket` with a given
262*61c4878aSAndroid Build Coastguard Worker    maximum block inner size.
263*61c4878aSAndroid Build Coastguard Worker
264*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-typed_pool`: Efficiently creates and
265*61c4878aSAndroid Build Coastguard Worker  destroys objects of a single given type.
266*61c4878aSAndroid Build Coastguard Worker
267*61c4878aSAndroid Build Coastguard WorkerForwarding allocator implementations
268*61c4878aSAndroid Build Coastguard Worker====================================
269*61c4878aSAndroid Build Coastguard WorkerThis module provides several "forwarding" allocators, as described in
270*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-design-forwarding`. The following is an overview.
271*61c4878aSAndroid Build Coastguard WorkerConsult the :ref:`module-pw_allocator-api` for additional details.
272*61c4878aSAndroid Build Coastguard Worker
273*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-fallback_allocator`: Dispatches first to a
274*61c4878aSAndroid Build Coastguard Worker  primary allocator, and, if that fails, to a secondary allocator.
275*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-pmr_allocator`: Adapts an allocator to be a
276*61c4878aSAndroid Build Coastguard Worker  ``std::pmr::polymorphic_allocator``, which can be used with standard library
277*61c4878aSAndroid Build Coastguard Worker  containers that `use allocators`_, such as ``std::pmr::vector<T>``.
278*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-synchronized_allocator`: Synchronizes access to
279*61c4878aSAndroid Build Coastguard Worker  another allocator, allowing it to be used by multiple threads.
280*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_allocator-api-tracking_allocator`: Wraps another allocator and
281*61c4878aSAndroid Build Coastguard Worker  records its usage.
282*61c4878aSAndroid Build Coastguard Worker
283*61c4878aSAndroid Build Coastguard Worker.. _module-pw_allocator-guide-custom_allocator:
284*61c4878aSAndroid Build Coastguard Worker
285*61c4878aSAndroid Build Coastguard WorkerCustom allocator implementations
286*61c4878aSAndroid Build Coastguard Worker================================
287*61c4878aSAndroid Build Coastguard WorkerIf none of the allocator implementations provided by this module meet your
288*61c4878aSAndroid Build Coastguard Workerneeds, you can implement your allocator and pass it into any routine that uses
289*61c4878aSAndroid Build Coastguard Workerthe generic interface.
290*61c4878aSAndroid Build Coastguard Worker
291*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-allocator` uses an `NVI`_ pattern. To add a custom
292*61c4878aSAndroid Build Coastguard Workerallocator implementation, you must at a miniumum implement the ``DoAllocate``
293*61c4878aSAndroid Build Coastguard Workerand ``DoDeallocate`` methods.
294*61c4878aSAndroid Build Coastguard Worker
295*61c4878aSAndroid Build Coastguard WorkerFor example, the following is a forwarding allocator that simply writes to the
296*61c4878aSAndroid Build Coastguard Workerlog whenever a threshold is exceeded:
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator.h
299*61c4878aSAndroid Build Coastguard Worker   :language: cpp
300*61c4878aSAndroid Build Coastguard Worker   :linenos:
301*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator]
302*61c4878aSAndroid Build Coastguard Worker
303*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator.cc
304*61c4878aSAndroid Build Coastguard Worker   :language: cpp
305*61c4878aSAndroid Build Coastguard Worker   :linenos:
306*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator]
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard WorkerThere are also several optional methods you can provide:
309*61c4878aSAndroid Build Coastguard Worker
310*61c4878aSAndroid Build Coastguard Worker- If an implementation of ``DoResize`` isn't provided, then ``Resize`` will
311*61c4878aSAndroid Build Coastguard Worker  always return false.
312*61c4878aSAndroid Build Coastguard Worker- If an implementation of ``DoReallocate`` isn't provided, then ``Reallocate``
313*61c4878aSAndroid Build Coastguard Worker  will try to ``Resize``, and, if unsuccessful, try to ``Allocate``, copy, and
314*61c4878aSAndroid Build Coastguard Worker  ``Deallocate``.
315*61c4878aSAndroid Build Coastguard Worker- If an implementation of ``DoGetInfo`` isn't provided, then ``GetInfo``
316*61c4878aSAndroid Build Coastguard Worker  will always return ``pw::Status::Unimplmented``.
317*61c4878aSAndroid Build Coastguard Worker
318*61c4878aSAndroid Build Coastguard WorkerCustom allocators can indicate which optional methods they implement and what
319*61c4878aSAndroid Build Coastguard Workeroptional behaviors they want from the base class by specifying
320*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-capabilities` when invoking the base class
321*61c4878aSAndroid Build Coastguard Workerconstructor.
322*61c4878aSAndroid Build Coastguard Worker
323*61c4878aSAndroid Build Coastguard Worker.. TODO: b/328076428 - Make Deallocate optional once traits supporting
324*61c4878aSAndroid Build Coastguard Worker   MonotonicAllocator are added.
325*61c4878aSAndroid Build Coastguard Worker
326*61c4878aSAndroid Build Coastguard Worker--------------------
327*61c4878aSAndroid Build Coastguard WorkerMeasure memory usage
328*61c4878aSAndroid Build Coastguard Worker--------------------
329*61c4878aSAndroid Build Coastguard WorkerYou can observe how much memory is being used for a particular use case using a
330*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-tracking_allocator`.
331*61c4878aSAndroid Build Coastguard Worker
332*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/metrics.cc
333*61c4878aSAndroid Build Coastguard Worker   :language: cpp
334*61c4878aSAndroid Build Coastguard Worker   :linenos:
335*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-metrics-custom_metrics1]
336*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-metrics-custom_metrics1]
337*61c4878aSAndroid Build Coastguard Worker
338*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/metrics.cc
339*61c4878aSAndroid Build Coastguard Worker   :language: cpp
340*61c4878aSAndroid Build Coastguard Worker   :linenos:
341*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-metrics-custom_metrics2]
342*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-metrics-custom_metrics2]
343*61c4878aSAndroid Build Coastguard Worker
344*61c4878aSAndroid Build Coastguard WorkerMetric data can be retrieved according to the steps described in
345*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_metric-exporting`, or by using the ``Dump`` method of
346*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_metric-group`:
347*61c4878aSAndroid Build Coastguard Worker
348*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/metrics.cc
349*61c4878aSAndroid Build Coastguard Worker   :language: cpp
350*61c4878aSAndroid Build Coastguard Worker   :linenos:
351*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-metrics-dump]
352*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-metrics-dump]
353*61c4878aSAndroid Build Coastguard Worker
354*61c4878aSAndroid Build Coastguard Worker
355*61c4878aSAndroid Build Coastguard WorkerThe ``CustomMetrics`` type used in the example above is a struct provided by the
356*61c4878aSAndroid Build Coastguard Workerdeveloper. You can create your own metrics structs that enable zero or more of
357*61c4878aSAndroid Build Coastguard Workerthe following metrics:
358*61c4878aSAndroid Build Coastguard Worker
359*61c4878aSAndroid Build Coastguard Worker- **requested_bytes**: The number of bytes currently requested from this
360*61c4878aSAndroid Build Coastguard Worker  allocator.
361*61c4878aSAndroid Build Coastguard Worker- **peak_requested_bytes**: The most bytes requested from this allocator at any
362*61c4878aSAndroid Build Coastguard Worker  one time.
363*61c4878aSAndroid Build Coastguard Worker- **cumulative_requested_bytes**: The total number of bytes that have been
364*61c4878aSAndroid Build Coastguard Worker  requested from this allocator across its lifetime.
365*61c4878aSAndroid Build Coastguard Worker- **allocated_bytes**: The number of bytes currently allocated by this
366*61c4878aSAndroid Build Coastguard Worker  allocator.
367*61c4878aSAndroid Build Coastguard Worker- **peak_allocated_bytes**: The most bytes allocated by this allocator at any
368*61c4878aSAndroid Build Coastguard Worker  one time.
369*61c4878aSAndroid Build Coastguard Worker- **cumulative_allocated_bytes**: The total number of bytes that have been
370*61c4878aSAndroid Build Coastguard Worker  allocated by this allocator across its lifetime.
371*61c4878aSAndroid Build Coastguard Worker- **num_allocations**: The number of allocation requests this allocator has
372*61c4878aSAndroid Build Coastguard Worker  successfully completed.
373*61c4878aSAndroid Build Coastguard Worker- **num_deallocations**: The number of deallocation requests this allocator has
374*61c4878aSAndroid Build Coastguard Worker  successfully completed.
375*61c4878aSAndroid Build Coastguard Worker- **num_resizes**: The number of resize requests this allocator has successfully
376*61c4878aSAndroid Build Coastguard Worker  completed.
377*61c4878aSAndroid Build Coastguard Worker- **num_reallocations**: The number of reallocation requests this allocator has
378*61c4878aSAndroid Build Coastguard Worker  successfully completed.
379*61c4878aSAndroid Build Coastguard Worker- **num_failures**: The number of requests this allocator has failed to
380*61c4878aSAndroid Build Coastguard Worker  complete.
381*61c4878aSAndroid Build Coastguard Worker
382*61c4878aSAndroid Build Coastguard WorkerIf you only want a subset of these metrics, you can implement your own metrics
383*61c4878aSAndroid Build Coastguard Workerstruct. For example:
384*61c4878aSAndroid Build Coastguard Worker
385*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/metrics.cc
386*61c4878aSAndroid Build Coastguard Worker   :language: cpp
387*61c4878aSAndroid Build Coastguard Worker   :linenos:
388*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-metrics-custom_metrics1]
389*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-metrics-custom_metrics1]
390*61c4878aSAndroid Build Coastguard Worker
391*61c4878aSAndroid Build Coastguard WorkerIf you have multiple routines that share an underlying allocator that you want
392*61c4878aSAndroid Build Coastguard Workerto track separately, you can create multiple tracking allocators that forward to
393*61c4878aSAndroid Build Coastguard Workerthe same underlying allocator:
394*61c4878aSAndroid Build Coastguard Worker
395*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/metrics.cc
396*61c4878aSAndroid Build Coastguard Worker   :language: cpp
397*61c4878aSAndroid Build Coastguard Worker   :linenos:
398*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-metrics-multiple_trackers]
399*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-metrics-multiple_trackers]
400*61c4878aSAndroid Build Coastguard Worker
401*61c4878aSAndroid Build Coastguard WorkerMeasure fragmentation
402*61c4878aSAndroid Build Coastguard Worker=====================
403*61c4878aSAndroid Build Coastguard Worker
404*61c4878aSAndroid Build Coastguard WorkerIf you are using a :ref:`module-pw_allocator-api-block_allocator`, you can use
405*61c4878aSAndroid Build Coastguard Workerthe ``MeasureFragmentation`` method to examine how fragmented the heap is. This
406*61c4878aSAndroid Build Coastguard Workermethod returns a :ref:`module-pw_allocator-api-fragmentation` struct, which
407*61c4878aSAndroid Build Coastguard Workerincludes the "sum of squares" and the sum of the inner sizes of the current free
408*61c4878aSAndroid Build Coastguard Workerblocks. On a platform or host with floating point support, you can divide the
409*61c4878aSAndroid Build Coastguard Workersquare root of the sum of squares by the sum to obtain a number that ranges from
410*61c4878aSAndroid Build Coastguard Worker0 to 1 to indicate maximal and minimal fragmenation, respectively. Subtracting
411*61c4878aSAndroid Build Coastguard Workerthis number from 1 can give a more intuitive "fragmenation score".
412*61c4878aSAndroid Build Coastguard Worker
413*61c4878aSAndroid Build Coastguard WorkerFor example, consider a heap consisting of the following blocks:
414*61c4878aSAndroid Build Coastguard Worker
415*61c4878aSAndroid Build Coastguard Worker- 100 bytes in use.
416*61c4878aSAndroid Build Coastguard Worker- 200 bytes free.
417*61c4878aSAndroid Build Coastguard Worker- 50 bytes in use.
418*61c4878aSAndroid Build Coastguard Worker- 10 bytes free.
419*61c4878aSAndroid Build Coastguard Worker- 200 bytes in use.
420*61c4878aSAndroid Build Coastguard Worker- 300 bytes free.
421*61c4878aSAndroid Build Coastguard Worker
422*61c4878aSAndroid Build Coastguard WorkerFor such a heap, ``MeasureFragmentation`` will return 130100 and 510. The above
423*61c4878aSAndroid Build Coastguard Workercalculation gives a fragmentation score of ``1 - sqrt(130100) / 510``, which is
424*61c4878aSAndroid Build Coastguard Workerapproximately ``0.29``.
425*61c4878aSAndroid Build Coastguard Worker
426*61c4878aSAndroid Build Coastguard Worker.. TODO: b/328648868 - Add guide for heap-viewer and link to cli.rst.
427*61c4878aSAndroid Build Coastguard Worker
428*61c4878aSAndroid Build Coastguard Worker------------------------
429*61c4878aSAndroid Build Coastguard WorkerDetect memory corruption
430*61c4878aSAndroid Build Coastguard Worker------------------------
431*61c4878aSAndroid Build Coastguard WorkerThe :ref:`module-pw_allocator-design-block` class provides a few different
432*61c4878aSAndroid Build Coastguard Workermechanisms to help detect memory corruptions when they happen. First, on every
433*61c4878aSAndroid Build Coastguard Workerdeallocation it will check the integrity of the block header and assert if it
434*61c4878aSAndroid Build Coastguard Workerhas been modified.
435*61c4878aSAndroid Build Coastguard Worker
436*61c4878aSAndroid Build Coastguard WorkerAdditionally, you can enable poisoning to detect additional memory corruptions
437*61c4878aSAndroid Build Coastguard Workersuch as use-after-frees. The :ref:`module-pw_allocator-module-configuration` for
438*61c4878aSAndroid Build Coastguard Worker``pw_allocator`` includes the ``PW_ALLOCATOR_BLOCK_POISON_INTERVAL`` option,
439*61c4878aSAndroid Build Coastguard Workerwhich will "poison" every N-th ``Block``. Allocators "poison" blocks on
440*61c4878aSAndroid Build Coastguard Workerdeallocation by writing a set pattern to the usable memory, and later check on
441*61c4878aSAndroid Build Coastguard Workerallocation that the pattern is intact. If it's not, some routine has modified
442*61c4878aSAndroid Build Coastguard Workerunallocated memory.
443*61c4878aSAndroid Build Coastguard Worker
444*61c4878aSAndroid Build Coastguard Worker----------------------
445*61c4878aSAndroid Build Coastguard WorkerTest custom allocators
446*61c4878aSAndroid Build Coastguard Worker----------------------
447*61c4878aSAndroid Build Coastguard WorkerIf you create your own allocator implementation, it's strongly recommended that
448*61c4878aSAndroid Build Coastguard Workeryou test it as well. If you're creating a forwarding allocator, you can use
449*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-allocator_for_test`. This simple allocator
450*61c4878aSAndroid Build Coastguard Workerprovides its own backing storage and automatically frees any outstanding
451*61c4878aSAndroid Build Coastguard Workerallocations when it goes out of scope. It also tracks the most recent values
452*61c4878aSAndroid Build Coastguard Workerprovided as parameters to the interface methods.
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard WorkerFor example, the following tests the custom allocator from
455*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-guide-custom_allocator`:
456*61c4878aSAndroid Build Coastguard Worker
457*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator_test.cc
458*61c4878aSAndroid Build Coastguard Worker   :language: cpp
459*61c4878aSAndroid Build Coastguard Worker   :linenos:
460*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator-unit_test]
461*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-custom_allocator-unit_test]
462*61c4878aSAndroid Build Coastguard Worker
463*61c4878aSAndroid Build Coastguard WorkerYou can also extend the :ref:`module-pw_allocator-api-test_harness` to perform
464*61c4878aSAndroid Build Coastguard Workerpseudorandom sequences of allocations and deallocations, e.g. as part of a
465*61c4878aSAndroid Build Coastguard Workerperformance test:
466*61c4878aSAndroid Build Coastguard Worker
467*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator_test_harness.h
468*61c4878aSAndroid Build Coastguard Worker   :language: cpp
469*61c4878aSAndroid Build Coastguard Worker   :linenos:
470*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator-test_harness]
471*61c4878aSAndroid Build Coastguard Worker
472*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator_perf_test.cc
473*61c4878aSAndroid Build Coastguard Worker   :language: cpp
474*61c4878aSAndroid Build Coastguard Worker   :linenos:
475*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator-perf_test]
476*61c4878aSAndroid Build Coastguard Worker
477*61c4878aSAndroid Build Coastguard WorkerEven better, you can easily add fuzz tests for your allocator. This module
478*61c4878aSAndroid Build Coastguard Workeruses the :ref:`module-pw_allocator-api-test_harness` to integrate with
479*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_fuzzer` and provide
480*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-fuzzing_support`.
481*61c4878aSAndroid Build Coastguard Worker
482*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/custom_allocator_test.cc
483*61c4878aSAndroid Build Coastguard Worker   :language: cpp
484*61c4878aSAndroid Build Coastguard Worker   :linenos:
485*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-custom_allocator-fuzz_test]
486*61c4878aSAndroid Build Coastguard Worker   :end-before: [pw_allocator-examples-custom_allocator-fuzz_test]
487*61c4878aSAndroid Build Coastguard Worker
488*61c4878aSAndroid Build Coastguard Worker-----------------------------
489*61c4878aSAndroid Build Coastguard WorkerMeasure custom allocator size
490*61c4878aSAndroid Build Coastguard Worker-----------------------------
491*61c4878aSAndroid Build Coastguard WorkerIf you create your own allocator implementation, you may wish to measure its
492*61c4878aSAndroid Build Coastguard Workercode size, similar to measurements in the module's own
493*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-size-reports`. You can use ``pw_bloat`` and
494*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_allocator-api-size_reporter` to create size reports as described
495*61c4878aSAndroid Build Coastguard Workerin :ref:`bloat-howto`.
496*61c4878aSAndroid Build Coastguard Worker
497*61c4878aSAndroid Build Coastguard WorkerFor example, the C++ code for a size report binary might look like:
498*61c4878aSAndroid Build Coastguard Worker
499*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: examples/size_report.cc
500*61c4878aSAndroid Build Coastguard Worker   :language: cpp
501*61c4878aSAndroid Build Coastguard Worker   :linenos:
502*61c4878aSAndroid Build Coastguard Worker   :start-after: [pw_allocator-examples-size_report]
503*61c4878aSAndroid Build Coastguard Worker
504*61c4878aSAndroid Build Coastguard WorkerThe resulting binary could be compared with the binary produced from
505*61c4878aSAndroid Build Coastguard Workerpw_allocator/size_report/first_fit.cc to identify just the code added in this
506*61c4878aSAndroid Build Coastguard Workercase by ``CustomAllocator``.
507*61c4878aSAndroid Build Coastguard Worker
508*61c4878aSAndroid Build Coastguard WorkerFor example, the GN build rule to generate a size report might look liek:
509*61c4878aSAndroid Build Coastguard Worker
510*61c4878aSAndroid Build Coastguard Worker.. code-block::
511*61c4878aSAndroid Build Coastguard Worker
512*61c4878aSAndroid Build Coastguard Worker   pw_size_diff("size_report") {
513*61c4878aSAndroid Build Coastguard Worker     title = "Example size report"
514*61c4878aSAndroid Build Coastguard Worker     binaries = [
515*61c4878aSAndroid Build Coastguard Worker       {
516*61c4878aSAndroid Build Coastguard Worker         target = ":size_report"
517*61c4878aSAndroid Build Coastguard Worker         base = "$dir_pw_allocator/size_report:first_fit"
518*61c4878aSAndroid Build Coastguard Worker         label = "CustomAllocator"
519*61c4878aSAndroid Build Coastguard Worker       },
520*61c4878aSAndroid Build Coastguard Worker     ]
521*61c4878aSAndroid Build Coastguard Worker   }
522*61c4878aSAndroid Build Coastguard Worker
523*61c4878aSAndroid Build Coastguard WorkerThe size report produced by this rule would render as:
524*61c4878aSAndroid Build Coastguard Worker
525*61c4878aSAndroid Build Coastguard Worker.. include:: examples/custom_allocator_size_report
526*61c4878aSAndroid Build Coastguard Worker
527*61c4878aSAndroid Build Coastguard Worker.. _AllocatorAwareContainers: https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer
528*61c4878aSAndroid Build Coastguard Worker.. _NVI: https://en.wikipedia.org/wiki/Non-virtual_interface_pattern
529*61c4878aSAndroid Build Coastguard Worker.. _RAII: https://en.cppreference.com/w/cpp/language/raii
530*61c4878aSAndroid Build Coastguard Worker.. _repository: https://bazel.build/concepts/build-ref#repositories
531*61c4878aSAndroid Build Coastguard Worker.. _use allocators: https://en.cppreference.com/w/cpp/memory/uses_allocator
532