# Copyright 2020 The Pigweed Authors # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of # the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library") load("//pw_build:compatibility.bzl", "incompatible_with_mcu") load("//pw_build:pw_facade.bzl", "pw_facade") load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test") package( default_visibility = ["//visibility:public"], features = [ "-layering_check", "-ctad_warnings", ], ) licenses(["notice"]) constraint_setting( name = "backend_constraint_setting", ) # TODO: pwbug.dev/328679085 - Remove this alias once no-one uses it. alias( name = "facade", actual = "pw_malloc.facade", ) cc_library( name = "common", linkopts = [ # Link options that replace dynamic memory operations in standard # library with the pigweed malloc. "-Wl,--wrap=malloc", "-Wl,--wrap=free", "-Wl,--wrap=realloc", "-Wl,--wrap=calloc", "-Wl,--wrap=_malloc_r", "-Wl,--wrap=_realloc_r", "-Wl,--wrap=_free_r", "-Wl,--wrap=_calloc_r", ], visibility = ["//visibility:private"], deps = [ "//pw_allocator:allocator", "//pw_allocator:synchronized_allocator", "//pw_allocator:tracking_allocator", "//pw_bytes", "//pw_numeric:checked_arithmetic", ], ) pw_facade( name = "pw_malloc", srcs = ["malloc.cc"], hdrs = [ "public/pw_malloc/config.h", "public/pw_malloc/malloc.h", ], backend = ":backend", strip_include_prefix = "public", deps = [ ":common", ":config_override", "//pw_assert:check", ], alwayslink = 1, ) label_flag( name = "config_override", build_setting_default = "//pw_build:default_module_config", ) label_flag( name = "backend", build_setting_default = ":backend_multiplexer", ) constraint_value( name = "best_fit_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "best_fit_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) constraint_value( name = "bucket_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "bucket_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) constraint_value( name = "first_fit_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "dual_first_fit_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "first_fit_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "last_fit_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) constraint_value( name = "freelist_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) constraint_value( name = "worst_fit_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. constraint_value( name = "worst_fit_block_allocator_backend", constraint_setting = "//pw_malloc:backend_constraint_setting", ) # TODO(b/376730645): Remove deprecated backends. alias( name = "backend_multiplexer", actual = select({ "//pw_malloc:best_fit_block_allocator_backend": "//pw_malloc:best_fit", "//pw_malloc:bucket_allocator_backend": "//pw_malloc:bucket_allocator", "//pw_malloc:bucket_block_allocator_backend": "//pw_malloc:bucket_allocator", "//pw_malloc:dual_first_fit_block_allocator_backend": "//pw_malloc:first_fit", "//pw_malloc:first_fit_block_allocator_backend": "//pw_malloc:first_fit", "//pw_malloc:last_fit_block_allocator_backend": "//pw_malloc:first_fit", "//pw_malloc:worst_fit_block_allocator_backend": "//pw_malloc:worst_fit", "//pw_malloc_freelist:backend": "//pw_malloc:bucket_allocator", "//pw_malloc_freertos:backend": "//pw_malloc_freertos", "//conditions:default": "//pw_build:unspecified_backend", }), visibility = ["//targets:__pkg__"], ) cc_library( name = "best_fit", srcs = ["best_fit.cc"], features = ["-conversion_warnings"], deps = [ ":pw_malloc.facade", "//pw_allocator:best_fit", ], ) # TODO(b/376730645): Remove deprecated backends. cc_library( name = "best_fit_block_allocator", features = ["-conversion_warnings"], deps = [":best_fit"], ) cc_library( name = "bucket_allocator", srcs = ["bucket_allocator.cc"], features = ["-conversion_warnings"], deps = [ "//pw_allocator:bucket_allocator", "//pw_malloc:facade", ], ) # TODO(b/376730645): Remove deprecated backends. cc_library( name = "bucket_block_allocator", features = ["-conversion_warnings"], deps = [":bucket_allocator"], ) cc_library( name = "first_fit", srcs = ["first_fit.cc"], features = ["-conversion_warnings"], deps = [ "//pw_allocator:first_fit", "//pw_malloc:facade", ], ) # TODO(b/376730645): Remove deprecated backends. cc_library( name = "dual_first_fit_block_allocator", features = ["-conversion_warnings"], deps = [":first_fit"], ) # TODO(b/376730645): Remove deprecated backends. cc_library( name = "first_fit_block_allocator", features = ["-conversion_warnings"], deps = [":first_fit"], ) # TODO(b/376730645): Remove deprecated backends. cc_library( name = "last_fit_block_allocator", features = ["-conversion_warnings"], deps = [":first_fit"], ) cc_library( name = "worst_fit", srcs = ["worst_fit.cc"], features = ["-conversion_warnings"], deps = [ "//pw_allocator:worst_fit", "//pw_malloc:facade", ], ) cc_library( name = "testing", testonly = True, srcs = ["malloc.cc"], hdrs = [ "public/pw_malloc/config.h", "public/pw_malloc/internal/testing.h", "public/pw_malloc/malloc.h", ], defines = [ "PW_MALLOC_METRICS_INCLUDE=\\\"pw_malloc/internal/testing.h\\\"", "PW_MALLOC_METRICS_TYPE=::pw::malloc::internal::TestMetrics", "PW_MALLOC_BLOCK_OFFSET_TYPE=uint16_t", "PW_MALLOC_MIN_BUCKET_SIZE=64", "PW_MALLOC_NUM_BUCKETS=4", ], features = ["-conversion_warnings"], implementation_deps = [ "//pw_assert:check", "//pw_tokenizer:decoder", ], strip_include_prefix = "public", # Only run the test if no backend is set to ensure there is no system # allocator. target_compatible_with = select({ "//pw_malloc:best_fit_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:bucket_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:bucket_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:dual_first_fit_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:first_fit_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:last_fit_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc:worst_fit_block_allocator_backend": ["@platforms//:incompatible"], "//pw_malloc_freelist:backend": ["@platforms//:incompatible"], "//pw_malloc_freertos:backend": ["@platforms//:incompatible"], "//conditions:default": [], }) + # Currently only supported for host unit tests on Linux. select({ "@platforms//os:linux": [], "//conditions:default": ["@platforms//:incompatible"], }) + # Only run using the light framework, since gtest allocates objects before # the test fixture initializes the heap. select({ "//pw_unit_test:backend_is_light": [], "//conditions:default": ["@platforms//:incompatible"], }) + # Don't run with ASAN or TSAN, since they wrap malloc. select({ "//pw_toolchain/host_clang:asan_enabled": ["@platforms//:incompatible"], "//pw_toolchain/host_clang:tsan_enabled": ["@platforms//:incompatible"], "//conditions:default": [], }), visibility = ["//visibility:private"], deps = [ ":common", "//pw_tokenizer:decoder", "//pw_unit_test:light", ], ) pw_cc_test( name = "best_fit_test", srcs = [ "best_fit.cc", "malloc_test.cc", ], # TODO: b/379937425 - Enable when internal toolchains are sorted out. tags = ["manual"], deps = [ ":testing", "//pw_allocator:best_fit", ], ) pw_cc_test( name = "bucket_allocator_test", srcs = [ "bucket_allocator.cc", "malloc_test.cc", ], # TODO: b/379937425 - Enable when internal toolchains are sorted out. tags = ["manual"], deps = [ ":testing", "//pw_allocator:bucket_allocator", ], ) pw_cc_test( name = "first_fit_test", srcs = [ "first_fit.cc", "malloc_test.cc", ], # TODO: b/379937425 - Enable when internal toolchains are sorted out. tags = ["manual"], deps = [ ":testing", "//pw_allocator:first_fit", ], ) pw_cc_test( name = "worst_fit_test", srcs = [ "malloc_test.cc", "worst_fit.cc", ], # TODO: b/379937425 - Enable when internal toolchains are sorted out. tags = ["manual"], deps = [ ":testing", "//pw_allocator:worst_fit", ], ) filegroup( name = "doxygen", srcs = [ "public/pw_malloc/config.h", "public/pw_malloc/malloc.h", ], ) sphinx_docs_library( name = "docs", srcs = [ "backends.rst", "docs.rst", ], prefix = "pw_malloc/", target_compatible_with = incompatible_with_mcu(), )