1# Copyright 2023 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14 15import("//build_overrides/pigweed.gni") 16 17import("$dir_pw_bloat/bloat.gni") 18import("$dir_pw_build/module_config.gni") 19import("$dir_pw_build/target_types.gni") 20import("$dir_pw_docgen/docs.gni") 21import("$dir_pw_fuzzer/fuzz_test.gni") 22import("$dir_pw_sync/backend.gni") 23import("$dir_pw_thread/backend.gni") 24import("$dir_pw_unit_test/test.gni") 25 26group("pw_allocator") { 27 public_deps = [ ":allocator" ] 28} 29 30# Module configuration 31 32declare_args() { 33 # The build target that overrides the default configuration options for this 34 # module. This should point to a source set that provides defines through a 35 # public config (which may -include a file or add defines directly). 36 pw_allocator_CONFIG = pw_build_DEFAULT_MODULE_CONFIG 37} 38 39config("public_include_path") { 40 include_dirs = [ "public" ] 41 visibility = [ ":*" ] 42} 43 44pw_source_set("config") { 45 public = [ "public/pw_allocator/config.h" ] 46 public_configs = [ ":public_include_path" ] 47 public_deps = [ pw_allocator_CONFIG ] 48} 49 50config("test_config") { 51 defines = [ 52 "PW_ALLOCATOR_STRICT_VALIDATION=1", 53 "PW_ALLOCATOR_BLOCK_POISON_INTERVAL=4", 54 ] 55} 56 57# Libraries 58 59pw_source_set("allocator") { 60 public_configs = [ ":public_include_path" ] 61 public = [ "public/pw_allocator/allocator.h" ] 62 public_deps = [ 63 ":deallocator", 64 dir_pw_result, 65 ] 66 sources = [ "allocator.cc" ] 67} 68 69pw_source_set("allocator_as_pool") { 70 public_configs = [ ":public_include_path" ] 71 public = [ "public/pw_allocator/allocator_as_pool.h" ] 72 public_deps = [ 73 ":allocator", 74 ":pool", 75 dir_pw_status, 76 ] 77 sources = [ "allocator_as_pool.cc" ] 78} 79 80pw_source_set("best_fit") { 81 public_configs = [ ":public_include_path" ] 82 public = [ "public/pw_allocator/best_fit.h" ] 83 public_deps = [ 84 ":block_allocator", 85 ":config", 86 "block:detailed_block", 87 "bucket:fast_sorted", 88 "bucket:sorted", 89 ] 90} 91 92# TODO(b/376730645): Remove deprecated interfaces. 93pw_source_set("best_fit_block_allocator") { 94 public_configs = [ ":public_include_path" ] 95 public = [ "public/pw_allocator/best_fit_block_allocator.h" ] 96 public_deps = [ ":best_fit" ] 97} 98 99pw_source_set("block_allocator") { 100 public_configs = [ ":public_include_path" ] 101 public = [ "public/pw_allocator/block_allocator.h" ] 102 public_deps = [ 103 ":allocator", 104 ":fragmentation", 105 "block:allocatable", 106 "block:basic", 107 "block:iterable", 108 "block:poisonable", 109 "block:with_layout", 110 dir_pw_bytes, 111 dir_pw_result, 112 dir_pw_status, 113 ] 114 deps = [ dir_pw_assert ] 115 sources = [ "block_allocator.cc" ] 116} 117 118pw_source_set("bucket_allocator") { 119 public_configs = [ ":public_include_path" ] 120 public = [ "public/pw_allocator/bucket_allocator.h" ] 121 public_deps = [ 122 ":block_allocator", 123 "block:detailed_block", 124 "bucket:unordered", 125 dir_pw_status, 126 ] 127} 128 129# TODO(b/376730645): Remove deprecated interfaces. 130pw_source_set("bucket_block_allocator") { 131 public_configs = [ ":public_include_path" ] 132 public = [ "public/pw_allocator/bucket_block_allocator.h" ] 133 public_deps = [ ":bucket_allocator" ] 134} 135 136pw_source_set("buddy_allocator") { 137 public_configs = [ ":public_include_path" ] 138 public = [ "public/pw_allocator/buddy_allocator.h" ] 139 public_deps = [ 140 ":allocator", 141 "$dir_pw_containers:vector", 142 "block:basic", 143 "bucket:unordered", 144 dir_pw_bytes, 145 dir_pw_status, 146 ] 147 deps = [ 148 "$dir_pw_bytes:alignment", 149 "$dir_pw_third_party/fuchsia:stdcompat", 150 dir_pw_assert, 151 ] 152 sources = [ "buddy_allocator.cc" ] 153} 154 155pw_source_set("buffer") { 156 public_configs = [ ":public_include_path" ] 157 public = [ "public/pw_allocator/buffer.h" ] 158 public_deps = [ 159 dir_pw_bytes, 160 dir_pw_result, 161 ] 162 deps = [ 163 "$dir_pw_bytes:alignment", 164 dir_pw_assert, 165 ] 166} 167 168pw_source_set("bump_allocator") { 169 public_configs = [ ":public_include_path" ] 170 public = [ "public/pw_allocator/bump_allocator.h" ] 171 public_deps = [ 172 ":allocator", 173 "$dir_pw_bytes:alignment", 174 dir_pw_bytes, 175 ] 176 deps = [ ":buffer" ] 177 sources = [ "bump_allocator.cc" ] 178} 179 180pw_source_set("chunk_pool") { 181 public_configs = [ ":public_include_path" ] 182 public = [ "public/pw_allocator/chunk_pool.h" ] 183 public_deps = [ 184 ":pool", 185 dir_pw_bytes, 186 dir_pw_result, 187 ] 188 deps = [ 189 ":buffer", 190 "$dir_pw_assert:check", 191 "$dir_pw_bytes:alignment", 192 "$dir_pw_third_party/fuchsia:stdcompat", 193 ] 194 sources = [ "chunk_pool.cc" ] 195} 196 197pw_source_set("deallocator") { 198 sources = [ "unique_ptr.cc" ] 199 public = [ 200 "public/pw_allocator/capability.h", 201 "public/pw_allocator/deallocator.h", 202 "public/pw_allocator/layout.h", 203 "public/pw_allocator/unique_ptr.h", 204 ] 205 public_configs = [ ":public_include_path" ] 206 public_deps = [ 207 dir_pw_assert, 208 dir_pw_preprocessor, 209 dir_pw_result, 210 dir_pw_status, 211 ] 212} 213 214# TODO(b/376730645): Remove deprecated interfaces. 215pw_source_set("dual_first_fit_block_allocator") { 216 public_configs = [ ":public_include_path" ] 217 public = [ "public/pw_allocator/dual_first_fit_block_allocator.h" ] 218 public_deps = [ ":first_fit" ] 219} 220 221pw_source_set("fallback_allocator") { 222 public_configs = [ ":public_include_path" ] 223 public = [ "public/pw_allocator/fallback_allocator.h" ] 224 public_deps = [ 225 ":allocator", 226 ":deallocator", 227 dir_pw_result, 228 dir_pw_status, 229 ] 230 sources = [ "fallback_allocator.cc" ] 231 deps = [ "$dir_pw_assert:check" ] 232} 233 234pw_source_set("first_fit") { 235 public_configs = [ ":public_include_path" ] 236 public = [ "public/pw_allocator/first_fit.h" ] 237 public_deps = [ 238 ":block_allocator", 239 ":config", 240 "block:detailed_block", 241 "bucket:sequenced", 242 ] 243} 244 245# TODO(b/376730645): Remove deprecated interfaces. 246pw_source_set("first_fit_block_allocator") { 247 public_configs = [ ":public_include_path" ] 248 public = [ "public/pw_allocator/first_fit_block_allocator.h" ] 249 public_deps = [ ":first_fit" ] 250} 251 252pw_source_set("fragmentation") { 253 public_configs = [ ":public_include_path" ] 254 public = [ "public/pw_allocator/fragmentation.h" ] 255 sources = [ "fragmentation.cc" ] 256} 257 258pw_source_set("freelist_heap") { 259 public_configs = [ ":public_include_path" ] 260 public = [ "public/pw_allocator/freelist_heap.h" ] 261 public_deps = [ 262 ":bucket_allocator", 263 dir_pw_assert, 264 dir_pw_bytes, 265 dir_pw_preprocessor, 266 ] 267} 268 269# TODO(b/376730645): Remove deprecated interfaces. 270pw_source_set("last_fit_block_allocator") { 271 public_configs = [ ":public_include_path" ] 272 public = [ "public/pw_allocator/last_fit_block_allocator.h" ] 273 public_deps = [ ":first_fit" ] 274} 275 276pw_source_set("libc_allocator") { 277 public_configs = [ ":public_include_path" ] 278 public = [ "public/pw_allocator/libc_allocator.h" ] 279 public_deps = [ ":allocator" ] 280 sources = [ "libc_allocator.cc" ] 281} 282 283pw_source_set("null_allocator") { 284 public_configs = [ ":public_include_path" ] 285 public = [ "public/pw_allocator/null_allocator.h" ] 286 public_deps = [ ":allocator" ] 287 sources = [ "null_allocator.cc" ] 288} 289 290pw_source_set("pmr_allocator") { 291 public_configs = [ ":public_include_path" ] 292 public = [ "public/pw_allocator/pmr_allocator.h" ] 293 public_deps = [ 294 ":allocator", 295 ":config", 296 ] 297 sources = [ "pmr_allocator.cc" ] 298} 299 300pw_source_set("pool") { 301 public_configs = [ ":public_include_path" ] 302 public = [ "public/pw_allocator/pool.h" ] 303 public_deps = [ 304 ":deallocator", 305 dir_pw_bytes, 306 dir_pw_result, 307 ] 308} 309 310pw_source_set("synchronized_allocator") { 311 public_configs = [ ":public_include_path" ] 312 public = [ "public/pw_allocator/synchronized_allocator.h" ] 313 public_deps = [ 314 ":allocator", 315 "$dir_pw_sync:borrow", 316 ] 317} 318 319pw_source_set("tracking_allocator") { 320 public_configs = [ ":public_include_path" ] 321 public = [ 322 "public/pw_allocator/metrics.h", 323 "public/pw_allocator/tracking_allocator.h", 324 ] 325 public_deps = [ 326 ":allocator", 327 dir_pw_metric, 328 dir_pw_status, 329 ] 330 deps = [ dir_pw_assert ] 331} 332 333pw_source_set("typed_pool") { 334 public_configs = [ ":public_include_path" ] 335 public = [ "public/pw_allocator/typed_pool.h" ] 336 public_deps = [ 337 ":allocator", 338 ":chunk_pool", 339 dir_pw_bytes, 340 dir_pw_result, 341 ] 342} 343 344pw_source_set("worst_fit") { 345 public_configs = [ ":public_include_path" ] 346 public = [ "public/pw_allocator/worst_fit.h" ] 347 public_deps = [ 348 ":block_allocator", 349 ":config", 350 "block:detailed_block", 351 "bucket:fast_sorted", 352 "bucket:sorted", 353 ] 354} 355 356# TODO(b/376730645): Remove deprecated interfaces. 357pw_source_set("worst_fit_block_allocator") { 358 public_configs = [ ":public_include_path" ] 359 public = [ "public/pw_allocator/worst_fit_block_allocator.h" ] 360 public_deps = [ ":worst_fit" ] 361} 362 363# Test support 364 365pw_source_set("testing") { 366 public_configs = [ ":test_config" ] 367 public = [ "public/pw_allocator/testing.h" ] 368 public_deps = [ 369 ":allocator", 370 ":buffer", 371 ":first_fit", 372 ":tracking_allocator", 373 "$dir_pw_sync:interrupt_spin_lock", 374 dir_pw_bytes, 375 dir_pw_result, 376 dir_pw_status, 377 dir_pw_unit_test, 378 ] 379 deps = [ dir_pw_assert ] 380} 381 382pw_source_set("block_allocator_testing") { 383 public = [ "public/pw_allocator/block_allocator_testing.h" ] 384 public_deps = [ 385 ":block_allocator", 386 "block:testing", 387 dir_pw_unit_test, 388 ] 389 deps = [ 390 "$dir_pw_bytes:alignment", 391 "$dir_pw_third_party/fuchsia:stdcompat", 392 "block:detailed_block", 393 dir_pw_assert, 394 dir_pw_status, 395 ] 396 sources = [ "block_allocator_testing.cc" ] 397} 398 399pw_source_set("test_harness") { 400 public = [ "public/pw_allocator/test_harness.h" ] 401 public_deps = [ 402 ":allocator", 403 dir_pw_containers, 404 dir_pw_random, 405 ] 406 deps = [ 407 "$dir_pw_third_party/fuchsia:stdcompat", 408 dir_pw_assert, 409 ] 410 sources = [ "test_harness.cc" ] 411} 412 413pw_source_set("fuzzing") { 414 public = [ "public/pw_allocator/fuzzing.h" ] 415 public_deps = [ 416 ":test_harness", 417 "$dir_pw_fuzzer:fuzztest", 418 ] 419 sources = [ "fuzzing.cc" ] 420} 421 422# Tests 423 424pw_test("allocator_as_pool_test") { 425 deps = [ 426 ":allocator_as_pool", 427 ":testing", 428 ] 429 sources = [ "allocator_as_pool_test.cc" ] 430} 431 432pw_test("allocator_test") { 433 deps = [ 434 ":allocator", 435 ":testing", 436 ] 437 sources = [ "allocator_test.cc" ] 438} 439 440pw_test("best_fit_test") { 441 deps = [ 442 ":best_fit", 443 ":best_fit_block_allocator", 444 ":block_allocator_testing", 445 ] 446 sources = [ "best_fit_test.cc" ] 447} 448 449pw_test("bucket_allocator_test") { 450 deps = [ 451 ":block_allocator_testing", 452 ":bucket_allocator", 453 ":bucket_block_allocator", 454 ] 455 sources = [ "bucket_allocator_test.cc" ] 456} 457 458pw_test("buddy_allocator_test") { 459 deps = [ 460 ":buddy_allocator", 461 ":testing", 462 ] 463 sources = [ "buddy_allocator_test.cc" ] 464} 465 466pw_test("buffer_test") { 467 deps = [ 468 ":buffer", 469 ":testing", 470 "$dir_pw_third_party/fuchsia:stdcompat", 471 dir_pw_bytes, 472 dir_pw_result, 473 ] 474 sources = [ "buffer_test.cc" ] 475} 476 477pw_test("bump_allocator_test") { 478 deps = [ 479 ":bump_allocator", 480 ":testing", 481 "$dir_pw_third_party/fuchsia:stdcompat", 482 ] 483 sources = [ "bump_allocator_test.cc" ] 484} 485 486pw_test("chunk_pool_test") { 487 deps = [ 488 ":chunk_pool", 489 ":testing", 490 ] 491 sources = [ "chunk_pool_test.cc" ] 492} 493 494pw_test("fallback_allocator_test") { 495 deps = [ 496 ":fallback_allocator", 497 ":testing", 498 dir_pw_status, 499 ] 500 sources = [ "fallback_allocator_test.cc" ] 501} 502 503pw_test("first_fit_test") { 504 deps = [ 505 ":block_allocator_testing", 506 ":buffer", 507 ":dual_first_fit_block_allocator", 508 ":first_fit", 509 ":first_fit_block_allocator", 510 ":last_fit_block_allocator", 511 "$dir_pw_third_party/fuchsia:stdcompat", 512 ] 513 sources = [ "first_fit_test.cc" ] 514} 515 516pw_test("fragmentation_test") { 517 deps = [ 518 ":fragmentation", 519 ":testing", 520 ] 521 sources = [ "fragmentation_test.cc" ] 522} 523 524pw_test("freelist_heap_test") { 525 deps = [ 526 ":freelist_heap", 527 "$dir_pw_bytes:alignment", 528 "$dir_pw_third_party/fuchsia:stdcompat", 529 "block:testing", 530 ] 531 sources = [ "freelist_heap_test.cc" ] 532} 533 534pw_test("layout_test") { 535 deps = [ 536 ":deallocator", 537 ":testing", 538 ] 539 sources = [ "layout_test.cc" ] 540} 541 542pw_test("libc_allocator_test") { 543 deps = [ 544 ":libc_allocator", 545 ":testing", 546 ] 547 sources = [ "libc_allocator_test.cc" ] 548} 549 550pw_test("null_allocator_test") { 551 deps = [ 552 ":null_allocator", 553 ":testing", 554 ] 555 sources = [ "null_allocator_test.cc" ] 556} 557 558pw_test("pmr_allocator_test") { 559 deps = [ 560 ":pmr_allocator", 561 ":testing", 562 ] 563 sources = [ "pmr_allocator_test.cc" ] 564} 565 566pw_test("synchronized_allocator_test") { 567 enable_if = 568 pw_sync_BINARY_SEMAPHORE_BACKEND != "" && pw_sync_MUTEX_BACKEND != "" && 569 pw_sync_INTERRUPT_SPIN_LOCK_BACKEND != "" && 570 pw_thread_YIELD_BACKEND != "" && 571 pw_thread_TEST_THREAD_CONTEXT_BACKEND != "" 572 deps = [ 573 ":synchronized_allocator", 574 ":test_harness", 575 ":testing", 576 "$dir_pw_sync:binary_semaphore", 577 "$dir_pw_sync:interrupt_spin_lock", 578 "$dir_pw_sync:mutex", 579 "$dir_pw_sync:virtual_basic_lockable", 580 "$dir_pw_thread:test_thread_context", 581 "$dir_pw_thread:thread", 582 "$dir_pw_thread:thread_core", 583 "$dir_pw_thread:yield", 584 dir_pw_random, 585 ] 586 sources = [ "synchronized_allocator_test.cc" ] 587} 588 589pw_test("tracking_allocator_test") { 590 deps = [ 591 ":testing", 592 ":tracking_allocator", 593 ] 594 sources = [ "tracking_allocator_test.cc" ] 595} 596 597pw_test("typed_pool_test") { 598 deps = [ 599 ":testing", 600 ":typed_pool", 601 "$dir_pw_bytes:alignment", 602 ] 603 sources = [ "typed_pool_test.cc" ] 604} 605 606pw_test("unique_ptr_test") { 607 deps = [ ":testing" ] 608 sources = [ "unique_ptr_test.cc" ] 609} 610 611pw_test("worst_fit_test") { 612 deps = [ 613 ":block_allocator_testing", 614 ":worst_fit", 615 ":worst_fit_block_allocator", 616 ] 617 sources = [ "worst_fit_test.cc" ] 618} 619 620pw_test_group("tests") { 621 tests = [ 622 ":allocator_as_pool_test", 623 624 # ":allocator_nc_test", 625 ":allocator_test", 626 ":best_fit_test", 627 ":bucket_allocator_test", 628 ":buddy_allocator_test", 629 ":buffer_test", 630 ":bump_allocator_test", 631 ":chunk_pool_test", 632 ":fallback_allocator_test", 633 ":first_fit_test", 634 ":fragmentation_test", 635 ":freelist_heap_test", 636 ":layout_test", 637 ":libc_allocator_test", 638 ":null_allocator_test", 639 ":pmr_allocator_test", 640 ":synchronized_allocator_test", 641 ":tracking_allocator_test", 642 ":typed_pool_test", 643 ":unique_ptr_test", 644 ":worst_fit_test", 645 ] 646 group_deps = [ 647 "benchmarks:tests", 648 "block:tests", 649 "bucket:tests", 650 "examples", 651 ] 652} 653 654# Docs 655 656pw_source_set("size_reporter") { 657 public_configs = [ ":public_include_path" ] 658 public = [ "public/pw_allocator/size_reporter.h" ] 659 public_deps = [ 660 ":null_allocator", 661 "$dir_pw_bloat:bloat_this_binary", 662 dir_pw_bytes, 663 ] 664} 665 666pw_size_diff("allocator_api_size_report") { 667 title = "Size of an empty implmentation of the Allocator interface" 668 binaries = [ 669 { 670 target = "size_report:null_allocator" 671 base = "size_report:base" 672 label = "NullAllocator" 673 }, 674 ] 675} 676 677pw_size_diff("concrete_allocators_size_report") { 678 title = "Sizes of various concrete allocator implementations" 679 binaries = [ 680 { 681 target = "size_report:best_fit" 682 base = "size_report:null_allocator" 683 label = "BestFitAllocator" 684 }, 685 { 686 target = "size_report:buddy_allocator" 687 base = "size_report:null_allocator" 688 label = "BuddyAllocator" 689 }, 690 { 691 target = "size_report:bump_allocator" 692 base = "size_report:null_allocator" 693 label = "BumpAllocator" 694 }, 695 { 696 target = "size_report:first_fit" 697 base = "size_report:null_allocator" 698 label = "FirstFitAllocator" 699 }, 700 { 701 target = "size_report:libc_allocator" 702 base = "size_report:null_allocator" 703 label = "LibCAllocator" 704 }, 705 { 706 target = "size_report:worst_fit" 707 base = "size_report:null_allocator" 708 label = "WorstFitAllocator" 709 }, 710 ] 711} 712 713pw_size_diff("forwarding_allocators_size_report") { 714 title = "Sizes of various forwarding allocator implementations" 715 binaries = [ 716 { 717 target = "size_report:fallback_allocator" 718 base = "size_report:fallback_allocator_base" 719 label = "FallbackAllocator" 720 }, 721 { 722 target = "size_report:pmr_allocator" 723 base = "size_report:pmr_allocator_base" 724 label = "AsPmrAllocator" 725 }, 726 { 727 target = "size_report:synchronized_allocator_isl" 728 base = "size_report:first_fit" 729 label = "SynchronizedAllocator<sync::InterruptSpinLock>" 730 }, 731 { 732 target = "size_report:synchronized_allocator_mutex" 733 base = "size_report:first_fit" 734 label = "SynchronizedAllocator<sync::Mutex>" 735 }, 736 { 737 target = "size_report:tracking_allocator_all_metrics" 738 base = "size_report:first_fit" 739 label = "TrackingAllocator<AllMetrics>" 740 }, 741 { 742 target = "size_report:tracking_allocator_no_metrics" 743 base = "size_report:first_fit" 744 label = "TrackingAllocator<NoMetrics>" 745 }, 746 ] 747} 748 749pw_size_diff("allocator_utilities_size_report") { 750 title = "Sizes of various allocator utility classes" 751 binaries = [ 752 { 753 target = "size_report:unique_ptr" 754 base = "size_report:first_fit" 755 label = "UniquePtr" 756 }, 757 ] 758} 759 760pw_doc_group("docs") { 761 inputs = [ 762 "doc_resources/pw_allocator_heap_visualizer_demo.png", 763 "examples/basic.cc", 764 "examples/block_allocator.cc", 765 "examples/custom_allocator_perf_test.cc", 766 "examples/custom_allocator_test_harness.h", 767 "examples/custom_allocator_test.cc", 768 "examples/custom_allocator.cc", 769 "examples/custom_allocator.h", 770 "examples/linker_sections.cc", 771 "examples/metrics.cc", 772 "examples/pmr.cc", 773 "examples/size_report.cc", 774 "examples/spin_lock.cc", 775 ] 776 sources = [ 777 "api.rst", 778 "code_size.rst", 779 "design.rst", 780 "docs.rst", 781 "guide.rst", 782 ] 783 report_deps = [ 784 ":allocator_api_size_report", 785 ":concrete_allocators_size_report", 786 ":forwarding_allocators_size_report", 787 "examples:custom_allocator_size_report", 788 ] 789} 790