Skip to content

Commit

Permalink
pw_allocator: Make assertions more tunable
Browse files Browse the repository at this point in the history
Previously, assertions in pw_allocator were either always enabled or
only enabled when "strict" validation was requested. These assertions
have been observed to prevent the compiler from being able to
effectively inline various CRTP-style classes. In many cases, they
represent internal checks rather than checks at the API boundary or when
reading (possibly corrupted) metadata.

As a result, the module configuration has been updated to allow
finer-grained control of assertions, which in turn allows consumers to
find the right balance of validation, performance, and code size for
their needs.

Change-Id: Ib1c5a13f493e5c77d71eb4b318d19a2e38e67cf9
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/264641
Reviewed-by: Wyatt Hepler <[email protected]>
Lint: Lint 🤖 <[email protected]>
Commit-Queue: Aaron Green <[email protected]>
  • Loading branch information
nopsledder authored and CQ Bot Account committed Feb 19, 2025
1 parent dcd8f58 commit 60a1d0c
Show file tree
Hide file tree
Showing 33 changed files with 675 additions and 422 deletions.
37 changes: 32 additions & 5 deletions pw_allocator/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,25 @@ label_flag(
build_setting_default = "//pw_build:default_module_config",
)

cc_library(
name = "hardening_basic",
defines = ["PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_BASIC"],
)

cc_library(
name = "hardening_robust",
defines = ["PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_ROBUST"],
)

cc_library(
name = "hardening_debug",
defines = ["PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_DEBUG"],
)

cc_library(
name = "test_config",
defines = [
"PW_ALLOCATOR_STRICT_VALIDATION=1",
"PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_DEBUG",
"PW_ALLOCATOR_BLOCK_POISON_INTERVAL=4",
],
)
Expand Down Expand Up @@ -105,6 +120,7 @@ cc_library(
":config",
":deallocator",
":fragmentation",
":hardening",
"//pw_allocator/block:allocatable",
"//pw_allocator/block:basic",
"//pw_allocator/block:iterable",
Expand Down Expand Up @@ -150,6 +166,7 @@ cc_library(
strip_include_prefix = "public",
deps = [
":allocator",
":hardening",
"//pw_allocator/block:basic",
"//pw_allocator/bucket:unordered",
"//pw_bytes",
Expand Down Expand Up @@ -215,7 +232,7 @@ cc_library(
],
strip_include_prefix = "public",
deps = [
"//pw_assert",
":hardening",
"//pw_preprocessor",
"//pw_result",
"//pw_status",
Expand Down Expand Up @@ -277,8 +294,18 @@ cc_library(
strip_include_prefix = "public",
deps = [
":bucket_allocator",
"//pw_assert",
":hardening",
"//pw_bytes",
],
)

cc_library(
name = "hardening",
hdrs = ["public/pw_allocator/hardening.h"],
strip_include_prefix = "public",
deps = [
":config",
"//pw_assert",
"//pw_preprocessor",
],
)
Expand Down Expand Up @@ -390,10 +417,9 @@ cc_library(
hdrs = ["public/pw_allocator/typed_pool.h"],
strip_include_prefix = "public",
deps = [
":allocator",
":chunk_pool",
":hardening",
"//pw_bytes",
"//pw_result",
],
)

Expand Down Expand Up @@ -431,6 +457,7 @@ cc_library(
":allocator",
":buffer",
":first_fit",
":hardening",
":test_config",
":tracking_allocator",
"//pw_assert",
Expand Down
55 changes: 50 additions & 5 deletions pw_allocator/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,21 @@ pw_source_set("config") {
public_deps = [ pw_allocator_CONFIG ]
}

config("hardening_basic") {
defines = [ "PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_BASIC" ]
}

config("hardening_robust") {
defines = [ "PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_ROBUST" ]
}

config("hardening_debug") {
defines = [ "PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_DEBUG" ]
}

config("test_config") {
defines = [
"PW_ALLOCATOR_STRICT_VALIDATION=1",
"PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_DEBUG",
"PW_ALLOCATOR_BLOCK_POISON_INTERVAL=4",
]
}
Expand Down Expand Up @@ -105,6 +117,7 @@ pw_source_set("block_allocator") {
":config",
":deallocator",
":fragmentation",
":hardening",
"block:allocatable",
"block:basic",
"block:iterable",
Expand Down Expand Up @@ -142,6 +155,7 @@ pw_source_set("buddy_allocator") {
public = [ "public/pw_allocator/buddy_allocator.h" ]
public_deps = [
":allocator",
":hardening",
"$dir_pw_containers:vector",
"block:basic",
"bucket:unordered",
Expand Down Expand Up @@ -211,7 +225,7 @@ pw_source_set("deallocator") {
]
public_configs = [ ":public_include_path" ]
public_deps = [
dir_pw_assert,
":hardening",
dir_pw_preprocessor,
dir_pw_result,
dir_pw_status,
Expand Down Expand Up @@ -267,8 +281,17 @@ pw_source_set("freelist_heap") {
public = [ "public/pw_allocator/freelist_heap.h" ]
public_deps = [
":bucket_allocator",
dir_pw_assert,
":hardening",
dir_pw_bytes,
]
}

pw_source_set("hardening") {
public_configs = [ ":public_include_path" ]
public = [ "public/pw_allocator/hardening.h" ]
public_deps = [
":config",
dir_pw_assert,
dir_pw_preprocessor,
]
}
Expand Down Expand Up @@ -369,10 +392,9 @@ pw_source_set("typed_pool") {
public_configs = [ ":public_include_path" ]
public = [ "public/pw_allocator/typed_pool.h" ]
public_deps = [
":allocator",
":chunk_pool",
":hardening",
dir_pw_bytes,
dir_pw_result,
]
}

Expand Down Expand Up @@ -404,6 +426,7 @@ pw_source_set("testing") {
":allocator",
":buffer",
":first_fit",
":hardening",
":tracking_allocator",
dir_pw_bytes,
dir_pw_result,
Expand Down Expand Up @@ -747,6 +770,27 @@ pw_size_diff("blocks_size_report") {
]
}

pw_size_diff("hardening_size_report") {
title = "Size impact of various levels of pw_allocator hardening"
binaries = [
{
target = "size_report:detailed_block_basic"
base = "size_report:base"
label = "DetailedBlock with basic assertions enabled"
},
{
target = "size_report:detailed_block_robust"
base = "size_report:base"
label = "DetailedBlock with robust assertions enabled"
},
{
target = "size_report:detailed_block_debug"
base = "size_report:base"
label = "DetailedBlock with debug assertions enabled"
},
]
}

pw_size_diff("buckets_size_report") {
title = "Sizes of various bucket implementations"
binaries = [
Expand Down Expand Up @@ -901,6 +945,7 @@ pw_doc_group("docs") {
":blocks_size_report",
":concrete_allocators_size_report",
":forwarding_allocators_size_report",
":hardening_size_report",
"examples:custom_allocator_size_report",
]
}
22 changes: 17 additions & 5 deletions pw_allocator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pw_add_library(pw_allocator.config INTERFACE

pw_add_library(pw_allocator.test_config INTERFACE
PUBLIC_DEFINES
PW_ALLOCATOR_STRICT_VALIDATION=1
PW_ALLOCATOR_HARDENING=PW_ALLOCATOR_HARDENING_DEBUG
PW_ALLOCATOR_BLOCK_POISON_INTERVAL=4
)

Expand Down Expand Up @@ -108,6 +108,7 @@ pw_add_library(pw_allocator.block_allocator STATIC
pw_allocator.block.poisonable
pw_allocator.block.with_layout
pw_allocator.fragmentation
pw_allocator.hardening
pw_bytes
pw_result
pw_status
Expand Down Expand Up @@ -144,6 +145,7 @@ pw_add_library(pw_allocator.buddy_allocator STATIC
pw_allocator.allocator
pw_allocator.block.basic
pw_allocator.bucket.unordered
pw_allocator.hardening
pw_bytes
pw_containers.vector
pw_status
Expand Down Expand Up @@ -211,7 +213,7 @@ pw_add_library(pw_allocator.deallocator STATIC
PUBLIC_INCLUDES
public
PUBLIC_DEPS
pw_assert
pw_allocator.hardening
pw_preprocessor
pw_result
pw_status
Expand Down Expand Up @@ -281,8 +283,18 @@ pw_add_library(pw_allocator.freelist_heap INTERFACE
public
PUBLIC_DEPS
pw_allocator.bucket_allocator
pw_assert
pw_allocator.hardening
pw_bytes
)

pw_add_library(pw_allocator.hardening INTERFACE
HEADERS
public/pw_allocator/hardening.h
PUBLIC_INCLUDES
public
PUBLIC_DEPS
pw_allocator.config
pw_assert
pw_preprocessor
)

Expand Down Expand Up @@ -399,10 +411,9 @@ pw_add_library(pw_allocator.typed_pool INTERFACE
PUBLIC_INCLUDES
public
PUBLIC_DEPS
pw_allocator.allocator
pw_allocator.chunk_pool
pw_allocator.hardening
pw_bytes
pw_result
)

pw_add_library(pw_allocator.worst_fit INTERFACE
Expand Down Expand Up @@ -440,6 +451,7 @@ pw_add_library(pw_allocator.testing INTERFACE
pw_allocator.allocator
pw_allocator.buffer
pw_allocator.first_fit
pw_allocator.hardening
pw_allocator.test_config
pw_allocator.tracking_allocator
pw_bytes
Expand Down
35 changes: 32 additions & 3 deletions pw_allocator/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ Deallocator
===========
Both ``Allocator`` and ``Pool`` derive from and extend ``Deallocator``. This
type is intended for allocator implementers and not for module consumers.
pw_allocator: Add bucket size reports

Separating out the bucket size reports from those of the blocks and
allocators makes it clearer where contributions to code size are coming
from.

Change-Id: Ibd719f3d4b88c42aa7833c24963e95253c397e03

.. doxygenclass:: pw::Deallocator
:members:
Expand All @@ -86,6 +93,28 @@ The ``UniquePtr`` smart pointer type can be created by any type deriving from
.. doxygenclass:: pw::UniquePtr
:members:

--------------------
Module configuration
--------------------

.. _module-pw_allocator-config-block_poison_interval:

PW_ALLOCATOR_BLOCK_POISON_INTERVAL
==================================
.. doxygendefine:: PW_ALLOCATOR_BLOCK_POISON_INTERVAL

.. _module-pw_allocator-config-hardening:

PW_ALLOCATOR_HARDENING
======================
.. doxygendefine:: PW_ALLOCATOR_HARDENING

.. _module-pw_allocator-config-suppress_deprecated_warnings:

PW_ALLOCATOR_SUPPRESS_DEPRECATED_WARNINGS
=========================================
.. doxygendefine:: PW_ALLOCATOR_SUPPRESS_DEPRECATED_WARNINGS

-------------------------
Allocator implementations
-------------------------
Expand All @@ -102,7 +131,7 @@ memory, and derive from this abstract base type.
.. doxygenclass:: pw::allocator::BlockAllocator
:members:

.. _module-pw_allocator-api-first_fit_allocator:
.. _module-pw_allocator-api-best_fit_allocator:

BestFitAllocator
----------------
Expand All @@ -116,14 +145,14 @@ BucketAllocator
.. doxygenclass:: pw::allocator::BucketAllocator
:members:

.. _module-pw_allocator-api-tlsf_allocator:
.. _module-pw_allocator-api-first_fit_allocator:

FirstFitAllocator
-----------------
.. doxygenclass:: pw::allocator::FirstFitAllocator
:members:

.. _module-pw_allocator-api-best_fit_allocator:
.. _module-pw_allocator-api-tlsf_allocator:

TlsfAllocator
-------------
Expand Down
Loading

0 comments on commit 60a1d0c

Please sign in to comment.