1# Copyright 2020 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 15load("//pw_build:pw_facade.bzl", "pw_facade") 16load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test") 17 18package(default_visibility = ["//visibility:public"]) 19 20licenses(["notice"]) 21 22constraint_setting( 23 name = "backend_constraint_setting", 24) 25 26# TODO: pwbug.dev/328679085 - Remove this alias once no-one uses it. 27alias( 28 name = "facade", 29 actual = "pw_malloc.facade", 30) 31 32_COMMON_SRCS = ["malloc.cc"] 33 34_COMMON_HDRS = [ 35 "public/pw_malloc/config.h", 36 "public/pw_malloc/malloc.h", 37] 38 39cc_library( 40 name = "common", 41 linkopts = [ 42 # Link options that replace dynamic memory operations in standard 43 # library with the pigweed malloc. 44 "-Wl,--wrap=malloc", 45 "-Wl,--wrap=free", 46 "-Wl,--wrap=realloc", 47 "-Wl,--wrap=calloc", 48 "-Wl,--wrap=_malloc_r", 49 "-Wl,--wrap=_realloc_r", 50 "-Wl,--wrap=_free_r", 51 "-Wl,--wrap=_calloc_r", 52 ], 53 visibility = ["//visibility:private"], 54 deps = [ 55 "//pw_allocator:allocator", 56 "//pw_allocator:synchronized_allocator", 57 "//pw_allocator:tracking_allocator", 58 "//pw_assert", 59 "//pw_bytes", 60 "//pw_preprocessor", 61 ], 62) 63 64pw_facade( 65 name = "pw_malloc", 66 srcs = _COMMON_SRCS, 67 hdrs = _COMMON_HDRS, 68 backend = ":backend", 69 strip_include_prefix = "public", 70 deps = [ 71 ":common", 72 ":config_override", 73 ], 74) 75 76label_flag( 77 name = "config_override", 78 build_setting_default = "//pw_build:default_module_config", 79) 80 81label_flag( 82 name = "backend", 83 build_setting_default = ":backend_multiplexer", 84) 85 86constraint_value( 87 name = "best_fit_backend", 88 constraint_setting = "//pw_malloc:backend_constraint_setting", 89) 90 91# TODO(b/376730645): Remove deprecated backends. 92constraint_value( 93 name = "best_fit_block_allocator_backend", 94 constraint_setting = "//pw_malloc:backend_constraint_setting", 95) 96 97constraint_value( 98 name = "bucket_allocator_backend", 99 constraint_setting = "//pw_malloc:backend_constraint_setting", 100) 101 102# TODO(b/376730645): Remove deprecated backends. 103constraint_value( 104 name = "bucket_block_allocator_backend", 105 constraint_setting = "//pw_malloc:backend_constraint_setting", 106) 107 108constraint_value( 109 name = "first_fit_backend", 110 constraint_setting = "//pw_malloc:backend_constraint_setting", 111) 112 113# TODO(b/376730645): Remove deprecated backends. 114constraint_value( 115 name = "dual_first_fit_block_allocator_backend", 116 constraint_setting = "//pw_malloc:backend_constraint_setting", 117) 118 119# TODO(b/376730645): Remove deprecated backends. 120constraint_value( 121 name = "first_fit_block_allocator_backend", 122 constraint_setting = "//pw_malloc:backend_constraint_setting", 123) 124 125# TODO(b/376730645): Remove deprecated backends. 126constraint_value( 127 name = "last_fit_block_allocator_backend", 128 constraint_setting = "//pw_malloc:backend_constraint_setting", 129) 130 131constraint_value( 132 name = "freelist_backend", 133 constraint_setting = "//pw_malloc:backend_constraint_setting", 134) 135 136constraint_value( 137 name = "worst_fit_backend", 138 constraint_setting = "//pw_malloc:backend_constraint_setting", 139) 140 141# TODO(b/376730645): Remove deprecated backends. 142constraint_value( 143 name = "worst_fit_block_allocator_backend", 144 constraint_setting = "//pw_malloc:backend_constraint_setting", 145) 146 147# TODO(b/376730645): Remove deprecated backends. 148alias( 149 name = "backend_multiplexer", 150 actual = select({ 151 "//pw_malloc:best_fit_block_allocator_backend": "//pw_malloc:best_fit", 152 "//pw_malloc:bucket_allocator_backend": "//pw_malloc:bucket_allocator", 153 "//pw_malloc:bucket_block_allocator_backend": "//pw_malloc:bucket_allocator", 154 "//pw_malloc:dual_first_fit_block_allocator_backend": "//pw_malloc:first_fit", 155 "//pw_malloc:first_fit_block_allocator_backend": "//pw_malloc:first_fit", 156 "//pw_malloc:last_fit_block_allocator_backend": "//pw_malloc:first_fit", 157 "//pw_malloc:worst_fit_block_allocator_backend": "//pw_malloc:worst_fit", 158 "//pw_malloc_freelist:backend": "//pw_malloc:bucket_allocator", 159 "//pw_malloc_freertos:backend": "//pw_malloc_freertos", 160 "//conditions:default": "//pw_build:unspecified_backend", 161 }), 162 visibility = ["//targets:__pkg__"], 163) 164 165cc_library( 166 name = "best_fit", 167 srcs = ["best_fit.cc"], 168 deps = [ 169 ":pw_malloc.facade", 170 "//pw_allocator:best_fit", 171 ], 172) 173 174# TODO(b/376730645): Remove deprecated backends. 175cc_library( 176 name = "best_fit_block_allocator", 177 deps = [":best_fit"], 178) 179 180cc_library( 181 name = "bucket_allocator", 182 srcs = ["bucket_allocator.cc"], 183 deps = [ 184 "//pw_allocator:bucket_allocator", 185 "//pw_malloc:facade", 186 ], 187) 188 189# TODO(b/376730645): Remove deprecated backends. 190cc_library( 191 name = "bucket_block_allocator", 192 deps = [":bucket_allocator"], 193) 194 195cc_library( 196 name = "first_fit", 197 srcs = ["first_fit.cc"], 198 deps = [ 199 "//pw_allocator:first_fit", 200 "//pw_malloc:facade", 201 ], 202) 203 204# TODO(b/376730645): Remove deprecated backends. 205cc_library( 206 name = "dual_first_fit_block_allocator", 207 deps = [":first_fit"], 208) 209 210# TODO(b/376730645): Remove deprecated backends. 211cc_library( 212 name = "first_fit_block_allocator", 213 deps = [":first_fit"], 214) 215 216# TODO(b/376730645): Remove deprecated backends. 217cc_library( 218 name = "last_fit_block_allocator", 219 deps = [":first_fit"], 220) 221 222cc_library( 223 name = "worst_fit", 224 srcs = ["worst_fit.cc"], 225 deps = [ 226 "//pw_allocator:worst_fit", 227 "//pw_malloc:facade", 228 ], 229) 230 231cc_library( 232 name = "testing", 233 testonly = True, 234 srcs = _COMMON_SRCS, 235 hdrs = _COMMON_HDRS + ["public/pw_malloc/internal/testing.h"], 236 defines = [ 237 "PW_MALLOC_METRICS_INCLUDE=\\\"pw_malloc/internal/testing.h\\\"", 238 "PW_MALLOC_METRICS_TYPE=::pw::malloc::internal::TestMetrics", 239 "PW_MALLOC_BLOCK_OFFSET_TYPE=uint16_t", 240 "PW_MALLOC_MIN_BUCKET_SIZE=64", 241 "PW_MALLOC_NUM_BUCKETS=4", 242 ], 243 implementation_deps = [ 244 "//pw_tokenizer:decoder", 245 ], 246 strip_include_prefix = "public", 247 248 # Only run the test if no backend is set to ensure there is no system 249 # allocator. 250 target_compatible_with = select({ 251 "//pw_malloc:best_fit_block_allocator_backend": ["@platforms//:incompatible"], 252 "//pw_malloc:bucket_allocator_backend": ["@platforms//:incompatible"], 253 "//pw_malloc:bucket_block_allocator_backend": ["@platforms//:incompatible"], 254 "//pw_malloc:dual_first_fit_block_allocator_backend": ["@platforms//:incompatible"], 255 "//pw_malloc:first_fit_block_allocator_backend": ["@platforms//:incompatible"], 256 "//pw_malloc:last_fit_block_allocator_backend": ["@platforms//:incompatible"], 257 "//pw_malloc:worst_fit_block_allocator_backend": ["@platforms//:incompatible"], 258 "//pw_malloc_freelist:backend": ["@platforms//:incompatible"], 259 "//pw_malloc_freertos:backend": ["@platforms//:incompatible"], 260 "//conditions:default": [], 261 }) + 262 263 # Currently only supported for host unit tests on Linux. 264 select({ 265 "@platforms//os:linux": [], 266 "//conditions:default": ["@platforms//:incompatible"], 267 }) + 268 269 # Only run using the light framework, since gtest allocates objects before 270 # the test fixture initializes the heap. 271 select({ 272 "//pw_unit_test:light_setting": [], 273 "//conditions:default": ["@platforms//:incompatible"], 274 }) + 275 276 # Don't run with ASAN or TSAN, since they wrap malloc. 277 select({ 278 "//pw_toolchain/host_clang:asan_enabled": ["@platforms//:incompatible"], 279 "//pw_toolchain/host_clang:tsan_enabled": ["@platforms//:incompatible"], 280 "//conditions:default": [], 281 }), 282 visibility = ["//visibility:private"], 283 deps = [ 284 ":common", 285 "//pw_tokenizer:decoder", 286 "//pw_unit_test:light", 287 ], 288) 289 290pw_cc_test( 291 name = "best_fit_test", 292 srcs = [ 293 "best_fit.cc", 294 "malloc_test.cc", 295 ], 296 # TODO: b/379937425 - Enable when internal toolchains are sorted out. 297 tags = ["manual"], 298 deps = [ 299 ":testing", 300 "//pw_allocator:best_fit", 301 ], 302) 303 304pw_cc_test( 305 name = "bucket_allocator_test", 306 srcs = [ 307 "bucket_allocator.cc", 308 "malloc_test.cc", 309 ], 310 # TODO: b/379937425 - Enable when internal toolchains are sorted out. 311 tags = ["manual"], 312 deps = [ 313 ":testing", 314 "//pw_allocator:bucket_allocator", 315 ], 316) 317 318pw_cc_test( 319 name = "first_fit_test", 320 srcs = [ 321 "first_fit.cc", 322 "malloc_test.cc", 323 ], 324 # TODO: b/379937425 - Enable when internal toolchains are sorted out. 325 tags = ["manual"], 326 deps = [ 327 ":testing", 328 "//pw_allocator:first_fit", 329 ], 330) 331 332pw_cc_test( 333 name = "worst_fit_test", 334 srcs = [ 335 "malloc_test.cc", 336 "worst_fit.cc", 337 ], 338 # TODO: b/379937425 - Enable when internal toolchains are sorted out. 339 tags = ["manual"], 340 deps = [ 341 ":testing", 342 "//pw_allocator:worst_fit", 343 ], 344) 345 346filegroup( 347 name = "doxygen", 348 srcs = [ 349 "public/pw_malloc/config.h", 350 "public/pw_malloc/malloc.h", 351 ], 352) 353