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