xref: /aosp_15_r20/external/pigweed/pw_allocator/BUILD.gn (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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