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("@bazel_skylib//lib:selects.bzl", "selects") 16load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") 17load("@rules_cc//cc:cc_library.bzl", "cc_library") 18load("@rules_python//python:proto.bzl", "py_proto_library") 19load("@rules_python//sphinxdocs:sphinx_docs_library.bzl", "sphinx_docs_library") 20load("//pw_build:compatibility.bzl", "HOST_PLATFORMS", "host_backend_alias", "incompatible_with_mcu") 21load("//pw_build:pw_facade.bzl", "pw_facade") 22load( 23 "//pw_protobuf_compiler:pw_proto_library.bzl", 24 "pwpb_proto_library", 25 "raw_rpc_proto_library", 26) 27load("//pw_unit_test:pw_cc_test.bzl", "pw_cc_test") 28 29package( 30 default_visibility = ["//visibility:public"], 31 features = ["-layering_check"], 32) 33 34licenses(["notice"]) 35 36pw_facade( 37 name = "id", 38 hdrs = [ 39 "public/pw_thread/id.h", 40 ], 41 backend = ":id_backend", 42 strip_include_prefix = "public", 43) 44 45label_flag( 46 name = "id_backend", 47 build_setting_default = ":id_unspecified_backend", 48) 49 50host_backend_alias( 51 name = "id_unspecified_backend", 52 backend = "//pw_thread_stl:id", 53) 54 55cc_library( 56 name = "config", 57 hdrs = ["public/pw_thread/config.h"], 58 strip_include_prefix = "public", 59 deps = [":config_override"], 60) 61 62label_flag( 63 name = "config_override", 64 build_setting_default = "//pw_build:default_module_config", 65) 66 67cc_library( 68 name = "thread_info", 69 hdrs = ["public/pw_thread/thread_info.h"], 70 strip_include_prefix = "public", 71 deps = ["//pw_span"], 72) 73 74pw_facade( 75 name = "thread_iteration", 76 hdrs = [ 77 "public/pw_thread/thread_iteration.h", 78 ], 79 backend = ":iteration_backend", 80 strip_include_prefix = "public", 81 deps = [ 82 ":thread_info", 83 "//pw_function", 84 "//pw_status", 85 ], 86) 87 88label_flag( 89 name = "iteration_backend", 90 build_setting_default = ":iteration_unspecified_backend", 91) 92 93host_backend_alias( 94 name = "iteration_unspecified_backend", 95 backend = "//pw_thread_stl:thread_iteration", 96) 97 98pw_facade( 99 name = "sleep", 100 srcs = [ 101 "sleep.cc", 102 ], 103 hdrs = [ 104 "public/pw_thread/sleep.h", 105 ], 106 backend = ":sleep_backend", 107 implementation_deps = [ 108 ":thread", 109 ], 110 strip_include_prefix = "public", 111 deps = [ 112 "//pw_chrono:system_clock", 113 "//pw_preprocessor", 114 ], 115) 116 117label_flag( 118 name = "sleep_backend", 119 build_setting_default = ":sleep_unspecified_backend", 120) 121 122host_backend_alias( 123 name = "sleep_unspecified_backend", 124 backend = "//pw_thread_stl:sleep", 125) 126 127pw_facade( 128 name = "thread", 129 srcs = ["public/pw_thread/config.h"], 130 hdrs = [ 131 "public/pw_thread/attrs.h", 132 "public/pw_thread/context.h", 133 "public/pw_thread/detached_thread.h", 134 "public/pw_thread/native_options.h", 135 "public/pw_thread/priority.h", 136 "public/pw_thread/stack.h", 137 "public/pw_thread/stack_not_supported.h", 138 "public/pw_thread/thread.h", 139 ], 140 backend = ":thread_backend", 141 strip_include_prefix = "public", 142 tags = ["noclangtidy"], 143 deps = [ 144 ":generic_priority", 145 ":id", 146 ":options", 147 ":thread_creation_backend", 148 "//pw_function", 149 "//pw_preprocessor", 150 "//pw_span", 151 ], 152) 153 154cc_library( 155 name = "options", 156 hdrs = ["public/pw_thread/options.h"], 157 strip_include_prefix = "public", 158) 159 160label_flag( 161 name = "thread_backend", 162 build_setting_default = ":thread_unspecified_backend", 163) 164 165host_backend_alias( 166 name = "thread_unspecified_backend", 167 backend = "//pw_thread_stl:thread", 168) 169 170label_flag( 171 name = "thread_creation_backend", 172 build_setting_default = ":thread_creation_default_backend", 173) 174 175alias( 176 name = "thread_creation_default_backend", 177 actual = selects.with_or({ 178 HOST_PLATFORMS: "//pw_thread_stl:thread_creation", 179 "//conditions:default": ":generic_thread_creation_unsupported", 180 }), 181) 182 183cc_library( 184 name = "thread_core", 185 hdrs = [ 186 "public/pw_thread/thread_core.h", 187 ], 188 strip_include_prefix = "public", 189 deps = ["//pw_function"], 190) 191 192cc_library( 193 name = "thread_snapshot_service", 194 srcs = [ 195 "pw_thread_private/thread_snapshot_service.h", 196 "thread_snapshot_service.cc", 197 ], 198 hdrs = ["public/pw_thread/thread_snapshot_service.h"], 199 implementation_deps = ["//pw_containers:vector"], 200 strip_include_prefix = "public", 201 tags = ["noclangtidy"], 202 deps = [ 203 "//pw_protobuf", 204 "//pw_rpc/raw:server_api", 205 "//pw_span", 206 "//pw_status", 207 ":config", 208 ":thread_pwpb", 209 ":thread_info", 210 ":thread_iteration", 211 ":thread_snapshot_service_pwpb", 212 ":thread_snapshot_service_raw_rpc", 213 # TODO(amontanez): This should depend on FreeRTOS but our third parties 214 # currently do not have Bazel support. 215 ], 216) 217 218cc_library( 219 name = "generic_thread_creation_unsupported", 220 hdrs = [ 221 "null_thread_creation_public_overrides/pw_thread_backend/context.h", 222 "null_thread_creation_public_overrides/pw_thread_backend/options.h", 223 "null_thread_creation_public_overrides/pw_thread_backend/priority.h", 224 "null_thread_creation_public_overrides/pw_thread_backend/stack.h", 225 ], 226 strip_include_prefix = "null_thread_creation_public_overrides", 227 tags = ["noclangtidy"], 228) 229 230pw_facade( 231 name = "test_thread_context", 232 hdrs = [ 233 "public/pw_thread/test_thread_context.h", 234 ], 235 backend = ":test_thread_context_backend", 236 strip_include_prefix = "public", 237) 238 239label_flag( 240 name = "test_thread_context_backend", 241 build_setting_default = ":test_thread_context_unspecified_backend", 242) 243 244host_backend_alias( 245 name = "test_thread_context_unspecified_backend", 246 backend = "//pw_thread_stl:test_thread_context", 247) 248 249pw_facade( 250 name = "yield", 251 srcs = [ 252 "yield.cc", 253 ], 254 hdrs = [ 255 "public/pw_thread/yield.h", 256 ], 257 backend = ":yield_backend", 258 implementation_deps = [ 259 ":thread", 260 ], 261 strip_include_prefix = "public", 262 deps = [ 263 "//pw_preprocessor", 264 ], 265) 266 267label_flag( 268 name = "yield_backend", 269 build_setting_default = ":yield_unspecified_backend", 270) 271 272host_backend_alias( 273 name = "yield_unspecified_backend", 274 backend = "//pw_thread_stl:yield", 275) 276 277cc_library( 278 name = "generic_priority", 279 hdrs = ["public/pw_thread/internal/priority.h"], 280 strip_include_prefix = "public", 281 visibility = ["//visibility:private"], 282 deps = [ 283 "//pw_assert:assert", 284 "//pw_numeric:integer_division", 285 "//pw_polyfill", 286 "//third_party/fuchsia:stdcompat", 287 ], 288) 289 290cc_library( 291 name = "snapshot", 292 srcs = [ 293 "snapshot.cc", 294 ], 295 hdrs = [ 296 "public/pw_thread/snapshot.h", 297 ], 298 strip_include_prefix = "public", 299 deps = [ 300 ":config", 301 ":thread", 302 ":thread_pwpb", 303 "//pw_bytes", 304 "//pw_function", 305 "//pw_log", 306 "//pw_protobuf", 307 "//pw_status", 308 ], 309) 310 311cc_library( 312 name = "non_portable_test_thread_options", 313 hdrs = [ 314 "public/pw_thread/non_portable_test_thread_options.h", 315 ], 316 strip_include_prefix = "public", 317 deps = [ 318 ":thread", 319 ], 320) 321 322# To instantiate this as a pw_cc_test, depend on this pw_cc_library and the 323# pw_cc_library which implements the backend for non_portable_test_thread_options. See 324# //pw_thread_stl:thread_backend_test as an example. 325cc_library( 326 name = "thread_facade_test", 327 testonly = True, 328 srcs = [ 329 "thread_facade_test.cc", 330 ], 331 deps = [ 332 ":non_portable_test_thread_options", 333 ":thread", 334 ":thread_core", 335 "//pw_chrono:system_clock", 336 "//pw_sync:binary_semaphore", 337 "//pw_unit_test", 338 ], 339 alwayslink = True, 340) 341 342pw_cc_test( 343 name = "test_thread_context_facade_test", 344 srcs = [ 345 "test_thread_context_facade_test.cc", 346 ], 347 # TODO: b/317922402 - On Windows, this test can easily hang indefinitely. 348 # Disable on Windows until we can test with the native Windows SDK libraries 349 # for threading. 350 # TODO: b/361369192 - This test behaves unusually on rp2. 351 target_compatible_with = select({ 352 "@pico-sdk//bazel/constraint:rp2040": ["@platforms//:incompatible"], 353 "@pico-sdk//bazel/constraint:rp2350": ["@platforms//:incompatible"], 354 "@platforms//os:windows": ["@platforms//:incompatible"], 355 "//conditions:default": [], 356 }), 357 deps = [ 358 ":test_thread_context", 359 ":thread", 360 "//pw_sync:binary_semaphore", 361 ], 362) 363 364pw_cc_test( 365 name = "id_facade_test", 366 srcs = [ 367 "id_facade_test.cc", 368 ], 369 deps = [":thread"], 370) 371 372pw_cc_test( 373 name = "options_test", 374 srcs = ["options_test.cc"], 375 deps = [ 376 ":options", 377 "//pw_compilation_testing:negative_compilation_testing", 378 ], 379) 380 381pw_cc_test( 382 name = "sleep_facade_test", 383 srcs = [ 384 "sleep_facade_test.cc", 385 "sleep_facade_test_c.c", 386 ], 387 deps = [ 388 ":sleep", 389 ":thread", 390 "//pw_chrono:system_clock", 391 "//pw_preprocessor", 392 ], 393) 394 395pw_cc_test( 396 name = "thread_info_test", 397 srcs = [ 398 "thread_info_test.cc", 399 ], 400 deps = [ 401 ":thread_info", 402 "//pw_span", 403 ], 404) 405 406pw_cc_test( 407 name = "thread_snapshot_service_test", 408 srcs = [ 409 "pw_thread_private/thread_snapshot_service.h", 410 "thread_snapshot_service_test.cc", 411 ], 412 # TODO: https://pwbug.dev/342662853 - This test fails under ASAN. 413 tags = [ 414 "noasan", 415 "noclangtidy", 416 ], 417 deps = [ 418 ":thread_info", 419 ":thread_iteration", 420 ":thread_pwpb", 421 ":thread_snapshot_service", 422 ":thread_snapshot_service_pwpb", 423 "//pw_protobuf", 424 "//pw_span", 425 "//pw_sync:thread_notification", 426 ], 427) 428 429pw_cc_test( 430 name = "priority_test", 431 srcs = ["priority_test.cc"], 432 deps = [ 433 ":generic_priority", 434 "//pw_compilation_testing:negative_compilation_testing", 435 "//pw_unit_test:constexpr", 436 ], 437) 438 439pw_cc_test( 440 name = "thread_creation_test", 441 srcs = ["thread_creation_test.cc"], 442 deps = [ 443 ":thread", 444 "//pw_compilation_testing:negative_compilation_testing", 445 ], 446) 447 448pw_cc_test( 449 name = "attrs_test", 450 srcs = ["attrs_test.cc"], 451 deps = [ 452 ":thread", 453 "//pw_compilation_testing:negative_compilation_testing", 454 "//pw_unit_test:constexpr", 455 ], 456) 457 458pw_cc_test( 459 name = "stack_test", 460 srcs = ["stack_test.cc"], 461 deps = [":thread"], 462) 463 464pw_cc_test( 465 name = "yield_facade_test", 466 srcs = [ 467 "yield_facade_test.cc", 468 "yield_facade_test_c.c", 469 ], 470 deps = [ 471 ":thread", 472 ":yield", 473 "//pw_preprocessor", 474 ], 475) 476 477proto_library( 478 name = "thread_proto", 479 srcs = ["pw_thread_protos/thread.proto"], 480 strip_import_prefix = "/pw_thread", 481 deps = [ 482 "//pw_tokenizer:tokenizer_proto", 483 ], 484) 485 486py_proto_library( 487 name = "thread_proto_py_pb2", 488 deps = [":thread_proto"], 489) 490 491proto_library( 492 name = "thread_snapshot_service_proto", 493 srcs = ["pw_thread_protos/thread_snapshot_service.proto"], 494 strip_import_prefix = "/pw_thread", 495 deps = [ 496 ":thread_proto", 497 ], 498) 499 500pwpb_proto_library( 501 name = "thread_snapshot_service_pwpb", 502 deps = [":thread_snapshot_service_proto"], 503) 504 505raw_rpc_proto_library( 506 name = "thread_snapshot_service_raw_rpc", 507 deps = [":thread_snapshot_service_proto"], 508) 509 510py_proto_library( 511 name = "thread_snapshot_service_py_pb2", 512 deps = [":thread_snapshot_service_proto"], 513) 514 515pwpb_proto_library( 516 name = "thread_pwpb", 517 deps = [":thread_proto"], 518) 519 520filegroup( 521 name = "doxygen", 522 srcs = [ 523 "public/pw_thread/attrs.h", 524 "public/pw_thread/context.h", 525 "public/pw_thread/internal/priority.h", 526 "public/pw_thread/options.h", 527 "public/pw_thread/priority.h", 528 "public/pw_thread/stack.h", 529 "public/pw_thread/test_thread_context.h", 530 "public/pw_thread/thread.h", 531 ], 532) 533 534sphinx_docs_library( 535 name = "docs", 536 srcs = [ 537 "backends.rst", 538 "docs.rst", 539 ], 540 prefix = "pw_thread/", 541 target_compatible_with = incompatible_with_mcu(), 542) 543