Merge branch 'master' into src_core_lib_security

pull/37069/head
tanvi-jagtap 8 months ago
commit b4b402faa2
  1. 4
      BUILD
  2. 136
      CMakeLists.txt
  3. 1
      Makefile
  4. 2
      Package.swift
  5. 2
      bazel/experiments.bzl
  6. 150
      build_autogenerated.yaml
  7. 1
      config.m4
  8. 1
      config.w32
  9. 10
      doc/core/latent_see.md
  10. 8
      doc/xds-test-descriptions.md
  11. 2
      gRPC-C++.podspec
  12. 3
      gRPC-Core.podspec
  13. 2
      grpc.gemspec
  14. 6
      include/grpc/support/port_platform.h
  15. 2
      package.xml
  16. 26
      src/core/BUILD
  17. 1
      src/core/ext/transport/chaotic_good/client_transport.cc
  18. 4
      src/core/ext/transport/chaotic_good/server_transport.cc
  19. 4
      src/core/lib/debug/trace_impl.h
  20. 7
      src/core/lib/event_engine/cf_engine/cf_engine.cc
  21. 9
      src/core/lib/event_engine/posix_engine/posix_engine.cc
  22. 15
      src/core/lib/event_engine/posix_engine/timer_manager.cc
  23. 8
      src/core/lib/event_engine/windows/windows_endpoint.cc
  24. 7
      src/core/lib/event_engine/windows/windows_engine.cc
  25. 32
      src/core/lib/experiments/config.cc
  26. 56
      src/core/lib/experiments/config.h
  27. 17
      src/core/lib/experiments/experiments.cc
  28. 50
      src/core/lib/experiments/experiments.h
  29. 1
      src/core/lib/experiments/rollouts.yaml
  30. 6
      src/core/lib/gprpp/work_serializer.cc
  31. 6
      src/core/lib/promise/activity.h
  32. 3
      src/core/lib/promise/party.cc
  33. 7
      src/core/lib/promise/party.h
  34. 10
      src/core/lib/surface/channel_init.cc
  35. 2
      src/core/lib/surface/client_call.cc
  36. 113
      src/core/util/latent_see.cc
  37. 214
      src/core/util/latent_see.h
  38. 69
      src/core/util/useful.h
  39. 1
      src/python/grpcio/grpc_core_dependencies.py
  40. 4
      test/core/call/client_call_test.cc
  41. 4
      test/core/call/corpus/client_call/clusterfuzz-testcase-minimized-client_call_fuzzer-4634405960482816
  42. 2
      test/core/experiments/bm_experiments.cc
  43. 8
      test/core/experiments/fixtures/experiments.h
  44. 12
      test/core/test_util/BUILD
  45. 131
      test/core/test_util/passthrough_endpoint.cc
  46. 95
      test/core/test_util/passthrough_endpoint.h
  47. 48
      test/core/transport/benchmarks/BUILD
  48. 93
      test/core/transport/benchmarks/bm_chaotic_good.cc
  49. 83
      test/core/transport/benchmarks/bm_inproc.cc
  50. 96
      test/core/transport/call_spine_benchmarks.h
  51. 138
      test/core/util/useful_test.cc
  52. 2
      tools/bazel.rc
  53. 4
      tools/bazelify_tests/test/portability_tests.bzl
  54. 2
      tools/codegen/core/experiments_compiler.py
  55. 1
      tools/distrib/python/grpcio_tools/MANIFEST.in
  56. 64
      tools/distrib/python/grpcio_tools/_spawn_patch.py
  57. 2
      tools/distrib/python/grpcio_tools/setup.py
  58. 2
      tools/doxygen/Doxyfile.c++.internal
  59. 1
      tools/doxygen/Doxyfile.core
  60. 3
      tools/doxygen/Doxyfile.core.internal
  61. 44
      tools/run_tests/generated/tests.json
  62. 15
      tools/run_tests/sanity/banned_functions.py

@ -2090,6 +2090,7 @@ grpc_cc_library(
"//src/core:if",
"//src/core:iomgr_fwd",
"//src/core:latch",
"//src/core:latent_see",
"//src/core:loop",
"//src/core:map",
"//src/core:match",
@ -3009,8 +3010,8 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/container:inlined_vector",
"absl/log",
"absl/log:check",
"absl/log:log",
],
language = "c++",
visibility = ["@grpc:client_channel"],
@ -3023,6 +3024,7 @@ grpc_cc_library(
"orphanable",
"stats",
"//src/core:experiments",
"//src/core:latent_see",
"//src/core:stats_data",
],
)

136
CMakeLists.txt generated

@ -889,6 +889,9 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_call_spine)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_chaotic_good)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_client_call)
endif()
@ -901,6 +904,9 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_http_client_filter)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_inproc)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c bm_party)
endif()
@ -2641,6 +2647,7 @@ add_library(grpc
src/core/util/json/json_reader.cc
src/core/util/json/json_util.cc
src/core/util/json/json_writer.cc
src/core/util/latent_see.cc
src/core/xds/grpc/certificate_provider_store.cc
src/core/xds/grpc/file_watcher_certificate_provider_factory.cc
src/core/xds/grpc/xds_audit_logger_registry.cc
@ -3357,6 +3364,7 @@ add_library(grpc_unsecure
src/core/util/json/json_object_loader.cc
src/core/util/json/json_reader.cc
src/core/util/json/json_writer.cc
src/core/util/latent_see.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
third_party/upb/upb/mini_descriptor/internal/base92.c
@ -5435,6 +5443,7 @@ add_library(grpc_authorization_provider
src/core/tsi/transport_security_grpc.cc
src/core/util/json/json_reader.cc
src/core/util/json/json_writer.cc
src/core/util/latent_see.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
third_party/upb/upb/mini_descriptor/internal/base92.c
@ -5869,6 +5878,51 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(bm_chaotic_good
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/ext/transport/chaotic_good/server_transport.cc
src/core/lib/transport/promise_endpoint.cc
test/core/test_util/passthrough_endpoint.cc
test/core/transport/benchmarks/bm_chaotic_good.cc
)
if(WIN32 AND MSVC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(bm_chaotic_good
PRIVATE
"GPR_DLL_IMPORTS"
"GRPC_DLL_IMPORTS"
)
endif()
endif()
target_compile_features(bm_chaotic_good PUBLIC cxx_std_14)
target_include_directories(bm_chaotic_good
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(bm_chaotic_good
${_gRPC_ALLTARGETS_LIBRARIES}
${_gRPC_BENCHMARK_LIBRARIES}
grpc
)
endif()
endif()
if(gRPC_BUILD_TESTS)
@ -6025,6 +6079,51 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
)
endif()
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(bm_inproc
src/core/ext/transport/chaotic_good/client_transport.cc
src/core/ext/transport/chaotic_good/frame.cc
src/core/ext/transport/chaotic_good/frame_header.cc
src/core/ext/transport/chaotic_good/server_transport.cc
src/core/lib/transport/promise_endpoint.cc
test/core/test_util/passthrough_endpoint.cc
test/core/transport/benchmarks/bm_inproc.cc
)
if(WIN32 AND MSVC)
if(BUILD_SHARED_LIBS)
target_compile_definitions(bm_inproc
PRIVATE
"GPR_DLL_IMPORTS"
"GRPC_DLL_IMPORTS"
)
endif()
endif()
target_compile_features(bm_inproc PUBLIC cxx_std_14)
target_include_directories(bm_inproc
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
)
target_link_libraries(bm_inproc
${_gRPC_ALLTARGETS_LIBRARIES}
${_gRPC_BENCHMARK_LIBRARIES}
grpc
)
endif()
endif()
if(gRPC_BUILD_TESTS)
@ -6280,7 +6379,9 @@ add_executable(activity_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/activity_test.cc
)
if(WIN32 AND MSVC)
@ -8581,6 +8682,7 @@ target_include_directories(bitset_test
target_link_libraries(bitset_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::check
)
@ -8842,6 +8944,7 @@ add_executable(call_filters_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/ref_counted_string.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
@ -8873,6 +8976,7 @@ add_executable(call_filters_test
src/core/lib/transport/parsed_metadata.cc
src/core/lib/transport/status_conversion.cc
src/core/lib/transport/timeout_encoding.cc
src/core/util/latent_see.cc
test/core/transport/call_filters_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -9097,8 +9201,10 @@ add_executable(call_state_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/lib/transport/call_state.cc
src/core/util/latent_see.cc
test/core/transport/call_state_test.cc
)
if(WIN32 AND MSVC)
@ -9421,6 +9527,7 @@ add_executable(call_utils_test
src/core/telemetry/stats_data.cc
src/core/tsi/alts/handshaker/transport_security_common_api.cc
src/core/util/json/json_writer.cc
src/core/util/latent_see.cc
test/core/call/call_utils_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -9858,6 +9965,7 @@ add_executable(cancel_callback_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -9876,6 +9984,7 @@ add_executable(cancel_callback_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/promise/cancel_callback_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -10966,6 +11075,7 @@ add_executable(chunked_vector_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -10984,6 +11094,7 @@ add_executable(chunked_vector_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/gprpp/chunked_vector_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -14276,6 +14387,7 @@ add_executable(exec_ctx_wakeup_scheduler_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -14288,6 +14400,7 @@ add_executable(exec_ctx_wakeup_scheduler_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/promise/exec_ctx_wakeup_scheduler_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -15077,6 +15190,7 @@ add_executable(flow_control_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -15096,6 +15210,7 @@ add_executable(flow_control_test
src/core/lib/slice/slice_buffer.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/transport/bdp_estimator.cc
src/core/util/latent_see.cc
test/core/transport/chttp2/flow_control_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -15164,6 +15279,7 @@ add_executable(for_each_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -15182,6 +15298,7 @@ add_executable(for_each_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/promise/for_each_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -18612,7 +18729,9 @@ add_executable(inter_activity_pipe_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/inter_activity_pipe_test.cc
)
if(WIN32 AND MSVC)
@ -18709,6 +18828,7 @@ add_executable(interceptor_list_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -18727,6 +18847,7 @@ add_executable(interceptor_list_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/promise/interceptor_list_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -19502,7 +19623,9 @@ add_executable(latch_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/latch_test.cc
)
if(WIN32 AND MSVC)
@ -19921,6 +20044,7 @@ add_executable(map_pipe_test
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/closure.cc
@ -19939,6 +20063,7 @@ add_executable(map_pipe_test
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/util/latent_see.cc
test/core/promise/map_pipe_test.cc
third_party/upb/upb/mini_descriptor/build_enum.c
third_party/upb/upb/mini_descriptor/decode.c
@ -20908,7 +21033,9 @@ add_executable(mpsc_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/mpsc_test.cc
)
if(WIN32 AND MSVC)
@ -21409,7 +21536,9 @@ add_executable(observable_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/observable_test.cc
)
if(WIN32 AND MSVC)
@ -23292,7 +23421,9 @@ add_executable(promise_mutex_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/promise_mutex_test.cc
)
if(WIN32 AND MSVC)
@ -30270,6 +30401,7 @@ target_include_directories(table_test
target_link_libraries(table_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::check
absl::type_traits
absl::utility
)
@ -32801,6 +32933,7 @@ target_link_libraries(unique_type_name_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::flat_hash_map
absl::check
absl::str_format
)
@ -32920,6 +33053,7 @@ target_include_directories(useful_test
target_link_libraries(useful_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::check
)
@ -33057,7 +33191,9 @@ add_executable(wait_for_callback_test
src/core/lib/debug/trace_flags.cc
src/core/lib/gprpp/dump_args.cc
src/core/lib/gprpp/glob.cc
src/core/lib/gprpp/per_cpu.cc
src/core/lib/promise/activity.cc
src/core/util/latent_see.cc
test/core/promise/wait_for_callback_test.cc
)
if(WIN32 AND MSVC)

1
Makefile generated

@ -1461,6 +1461,7 @@ LIBGRPC_SRC = \
src/core/util/json/json_reader.cc \
src/core/util/json/json_util.cc \
src/core/util/json/json_writer.cc \
src/core/util/latent_see.cc \
src/core/util/linux/cpu.cc \
src/core/util/linux/log.cc \
src/core/util/log.cc \

2
Package.swift generated

@ -1931,6 +1931,8 @@ let package = Package(
"src/core/util/json/json_util.h",
"src/core/util/json/json_writer.cc",
"src/core/util/json/json_writer.h",
"src/core/util/latent_see.cc",
"src/core/util/latent_see.h",
"src/core/util/linux/cpu.cc",
"src/core/util/linux/log.cc",
"src/core/util/log.cc",

@ -41,7 +41,7 @@ EXPERIMENT_ENABLES = {
"trace_record_callops": "trace_record_callops",
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
"work_serializer_dispatch": "event_engine_client,work_serializer_dispatch",
"work_serializer_dispatch": "work_serializer_dispatch",
}
EXPERIMENT_POLLERS = [

@ -1217,6 +1217,7 @@ libs:
- src/core/util/json/json_reader.h
- src/core/util/json/json_util.h
- src/core/util/json/json_writer.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- src/core/util/upb_utils.h
- src/core/xds/grpc/certificate_provider_store.h
@ -2023,6 +2024,7 @@ libs:
- src/core/util/json/json_reader.cc
- src/core/util/json/json_util.cc
- src/core/util/json/json_writer.cc
- src/core/util/latent_see.cc
- src/core/xds/grpc/certificate_provider_store.cc
- src/core/xds/grpc/file_watcher_certificate_provider_factory.cc
- src/core/xds/grpc/xds_audit_logger_registry.cc
@ -2690,6 +2692,7 @@ libs:
- src/core/util/json/json_object_loader.h
- src/core/util/json/json_reader.h
- src/core/util/json/json_writer.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- src/core/util/upb_utils.h
- third_party/upb/upb/generated_code_support.h
@ -3105,6 +3108,7 @@ libs:
- src/core/util/json/json_object_loader.cc
- src/core/util/json/json_reader.cc
- src/core/util/json/json_writer.cc
- src/core/util/latent_see.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
- third_party/upb/upb/mini_descriptor/internal/base92.c
@ -4750,6 +4754,7 @@ libs:
- src/core/util/json/json_args.h
- src/core/util/json/json_reader.h
- src/core/util/json/json_writer.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -5035,6 +5040,7 @@ libs:
- src/core/tsi/transport_security_grpc.cc
- src/core/util/json/json_reader.cc
- src/core/util/json/json_writer.cc
- src/core/util/latent_see.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
- third_party/upb/upb/mini_descriptor/internal/base92.c
@ -5157,6 +5163,43 @@ targets:
- linux
- posix
uses_polling: false
- name: bm_chaotic_good
build: test
language: c
headers:
- src/core/ext/transport/chaotic_good/chaotic_good_transport.h
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/ext/transport/chaotic_good/server_transport.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_latch.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/switch.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/test_util/passthrough_endpoint.h
- test/core/transport/call_spine_benchmarks.h
src:
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/ext/transport/chaotic_good/server_transport.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/test_util/passthrough_endpoint.cc
- test/core/transport/benchmarks/bm_chaotic_good.cc
deps:
- benchmark
- grpc
args:
- --benchmark_min_time=0.001s
benchmark: true
defaults: benchmark
platforms:
- linux
- posix
uses_polling: false
- name: bm_client_call
build: test
language: c
@ -5227,6 +5270,43 @@ targets:
- linux
- posix
uses_polling: false
- name: bm_inproc
build: test
language: c
headers:
- src/core/ext/transport/chaotic_good/chaotic_good_transport.h
- src/core/ext/transport/chaotic_good/client_transport.h
- src/core/ext/transport/chaotic_good/frame.h
- src/core/ext/transport/chaotic_good/frame_header.h
- src/core/ext/transport/chaotic_good/server_transport.h
- src/core/lib/promise/event_engine_wakeup_scheduler.h
- src/core/lib/promise/inter_activity_latch.h
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/mpsc.h
- src/core/lib/promise/switch.h
- src/core/lib/promise/wait_set.h
- src/core/lib/transport/promise_endpoint.h
- test/core/test_util/passthrough_endpoint.h
- test/core/transport/call_spine_benchmarks.h
src:
- src/core/ext/transport/chaotic_good/client_transport.cc
- src/core/ext/transport/chaotic_good/frame.cc
- src/core/ext/transport/chaotic_good/frame_header.cc
- src/core/ext/transport/chaotic_good/server_transport.cc
- src/core/lib/transport/promise_endpoint.cc
- test/core/test_util/passthrough_endpoint.cc
- test/core/transport/benchmarks/bm_inproc.cc
deps:
- benchmark
- grpc
args:
- --benchmark_min_time=0.001s
benchmark: true
defaults: benchmark
platforms:
- linux
- posix
uses_polling: false
- name: bm_party
build: test
language: c
@ -5359,6 +5439,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -5375,13 +5456,16 @@ targets:
- src/core/lib/promise/promise.h
- src/core/lib/promise/seq.h
- src/core/lib/promise/wait_set.h
- src/core/util/latent_see.h
- test/core/promise/test_wakeup_schedulers.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/activity_test.cc
deps:
- gtest
@ -6380,6 +6464,7 @@ targets:
- test/core/gprpp/bitset_test.cc
deps:
- gtest
- absl/log:check
uses_polling: false
- name: buffer_list_test
gtest: true
@ -6540,6 +6625,7 @@ targets:
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/packed_table.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/ref_counted_string.h
@ -6600,6 +6686,7 @@ targets:
- src/core/lib/transport/simple_slice_based_metadata.h
- src/core/lib/transport/status_conversion.h
- src/core/lib/transport/timeout_encoding.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- test/core/promise/poll_matcher.h
- third_party/upb/upb/generated_code_support.h
@ -6633,6 +6720,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/ref_counted_string.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
@ -6664,6 +6752,7 @@ targets:
- src/core/lib/transport/parsed_metadata.cc
- src/core/lib/transport/status_conversion.cc
- src/core/lib/transport/timeout_encoding.cc
- src/core/util/latent_see.cc
- test/core/transport/call_filters_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -6801,6 +6890,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -6811,14 +6901,17 @@ targets:
- src/core/lib/promise/poll.h
- src/core/lib/promise/status_flag.h
- src/core/lib/transport/call_state.h
- src/core/util/latent_see.h
- test/core/promise/poll_matcher.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/lib/transport/call_state.cc
- src/core/util/latent_see.cc
- test/core/transport/call_state_test.cc
deps:
- gtest
@ -7153,6 +7246,7 @@ targets:
- src/core/util/json/json.h
- src/core/util/json/json_args.h
- src/core/util/json/json_writer.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -7407,6 +7501,7 @@ targets:
- src/core/telemetry/stats_data.cc
- src/core/tsi/alts/handshaker/transport_security_common_api.cc
- src/core/util/json/json_writer.cc
- src/core/util/latent_see.cc
- test/core/call/call_utils_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -7796,6 +7891,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -7831,6 +7927,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -7860,6 +7957,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -7878,6 +7976,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/promise/cancel_callback_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -8616,6 +8715,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -8650,6 +8750,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -8679,6 +8780,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -8697,6 +8799,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/gprpp/chunked_vector_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -10200,6 +10303,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -10222,6 +10326,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -10251,6 +10356,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -10263,6 +10369,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/promise/exec_ctx_wakeup_scheduler_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -10760,6 +10867,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -10796,6 +10904,7 @@ targets:
- src/core/lib/slice/slice_string_helpers.h
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/http2_errors.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- third_party/upb/upb/generated_code_support.h
- third_party/upb/upb/mini_descriptor/build_enum.h
@ -10828,6 +10937,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -10847,6 +10957,7 @@ targets:
- src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/transport/bdp_estimator.cc
- src/core/util/latent_see.cc
- test/core/transport/chttp2/flow_control_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -10893,6 +11004,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -10936,6 +11048,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- test/core/promise/test_wakeup_schedulers.h
- third_party/upb/upb/generated_code_support.h
@ -10966,6 +11079,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -10984,6 +11098,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/promise/for_each_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -12532,6 +12647,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -12544,13 +12660,16 @@ targets:
- src/core/lib/promise/inter_activity_pipe.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/seq.h
- src/core/util/latent_see.h
- test/core/promise/test_wakeup_schedulers.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/inter_activity_pipe_test.cc
deps:
- gtest
@ -12595,6 +12714,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -12630,6 +12750,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- test/core/promise/test_context.h
- third_party/upb/upb/generated_code_support.h
@ -12660,6 +12781,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -12678,6 +12800,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/promise/interceptor_list_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -13111,6 +13234,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -13126,13 +13250,16 @@ targets:
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/seq.h
- src/core/util/latent_see.h
- test/core/promise/test_wakeup_schedulers.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/latch_test.cc
deps:
- gtest
@ -13301,6 +13428,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
@ -13344,6 +13472,7 @@ targets:
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_string_helpers.h
- src/core/util/latent_see.h
- src/core/util/spinlock.h
- test/core/promise/test_wakeup_schedulers.h
- third_party/upb/upb/generated_code_support.h
@ -13374,6 +13503,7 @@ targets:
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/closure.cc
@ -13392,6 +13522,7 @@ targets:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/util/latent_see.cc
- test/core/promise/map_pipe_test.cc
- third_party/upb/upb/mini_descriptor/build_enum.c
- third_party/upb/upb/mini_descriptor/decode.c
@ -13911,6 +14042,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -13922,13 +14054,16 @@ targets:
- src/core/lib/promise/poll.h
- src/core/lib/promise/promise.h
- src/core/lib/promise/wait_set.h
- src/core/util/latent_see.h
- test/core/promise/poll_matcher.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/mpsc_test.cc
deps:
- gtest
@ -14220,6 +14355,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/notification.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -14231,13 +14367,16 @@ targets:
- src/core/lib/promise/map.h
- src/core/lib/promise/observable.h
- src/core/lib/promise/poll.h
- src/core/util/latent_see.h
- test/core/promise/poll_matcher.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/observable_test.cc
deps:
- gtest
@ -15154,6 +15293,7 @@ targets:
- src/core/lib/gprpp/dump_args.h
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -15170,13 +15310,16 @@ targets:
- src/core/lib/promise/promise.h
- src/core/lib/promise/promise_mutex.h
- src/core/lib/promise/seq.h
- src/core/util/latent_see.h
- test/core/promise/test_wakeup_schedulers.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/promise_mutex_test.cc
deps:
- gtest
@ -19656,6 +19799,7 @@ targets:
- test/core/gprpp/table_test.cc
deps:
- gtest
- absl/log:check
- absl/meta:type_traits
- absl/utility:utility
uses_polling: false
@ -20856,6 +21000,7 @@ targets:
deps:
- gtest
- absl/container:flat_hash_map
- absl/log:check
- absl/strings:str_format
uses_polling: false
- name: unknown_frame_bad_client_test
@ -20892,6 +21037,7 @@ targets:
- test/core/util/useful_test.cc
deps:
- gtest
- absl/log:check
uses_polling: false
- name: uuid_v4_test
gtest: true
@ -20939,6 +21085,7 @@ targets:
- src/core/lib/gprpp/glob.h
- src/core/lib/gprpp/notification.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/per_cpu.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/promise/activity.h
@ -20949,13 +21096,16 @@ targets:
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/wait_for_callback.h
- src/core/util/latent_see.h
- test/core/promise/test_wakeup_schedulers.h
src:
- src/core/lib/debug/trace.cc
- src/core/lib/debug/trace_flags.cc
- src/core/lib/gprpp/dump_args.cc
- src/core/lib/gprpp/glob.cc
- src/core/lib/gprpp/per_cpu.cc
- src/core/lib/promise/activity.cc
- src/core/util/latent_see.cc
- test/core/promise/wait_for_callback_test.cc
deps:
- gtest

1
config.m4 generated

@ -836,6 +836,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/util/json/json_reader.cc \
src/core/util/json/json_util.cc \
src/core/util/json/json_writer.cc \
src/core/util/latent_see.cc \
src/core/util/linux/cpu.cc \
src/core/util/linux/log.cc \
src/core/util/log.cc \

1
config.w32 generated

@ -801,6 +801,7 @@ if (PHP_GRPC != "no") {
"src\\core\\util\\json\\json_reader.cc " +
"src\\core\\util\\json\\json_util.cc " +
"src\\core\\util\\json\\json_writer.cc " +
"src\\core\\util\\latent_see.cc " +
"src\\core\\util\\linux\\cpu.cc " +
"src\\core\\util\\linux\\log.cc " +
"src\\core\\util\\log.cc " +

@ -0,0 +1,10 @@
Latent-see
----------
This is a simple latency profiling tool.
We record various timestamps throughout program execution, and then at exit format json
to a file `latent_see.json` in the chrome event trace format. This format can be
consumed by various tools (eg ui.perfetto.dev).
Recording macros are documented in latent_see.h.

@ -16,6 +16,8 @@ Server should accept these arguments:
* --secure_mode=BOOLEAN
* When set to true it uses XdsServerCredentials with the test server for security test cases.
In case of secure mode, port and maintenance_port should be different.
* --enable-csm-observability=BOOLEAN
* When set to true, enable CSM Observability.
Servers that want to support dual stack testing (like Java) should also accept:
@ -64,6 +66,12 @@ Clients should accept these arguments:
* The timeout to set on all outbound RPCs. Default is 20.
* --secure_mode=BOOLEAN
* When set to true it uses XdsChannelCredentials with the test client for security test cases.
* --enable-csm-observability=BOOLEAN
* When set to true, enable CSM Observability.
* --request_payload_size=INT32
* Set the SimpleRequest.payload.body to a string of repeated '0' characters of the given size in bytes.
* --response_payload_size=INT32
* Ask the server to respond with SimpleResponse.payload.body of the given length.
### XdsUpdateClientConfigureService

2
gRPC-C++.podspec generated

@ -1321,6 +1321,7 @@ Pod::Spec.new do |s|
'src/core/util/json/json_reader.h',
'src/core/util/json/json_util.h',
'src/core/util/json/json_writer.h',
'src/core/util/latent_see.h',
'src/core/util/spinlock.h',
'src/core/util/string.h',
'src/core/util/time_precise.h',
@ -2596,6 +2597,7 @@ Pod::Spec.new do |s|
'src/core/util/json/json_reader.h',
'src/core/util/json/json_util.h',
'src/core/util/json/json_writer.h',
'src/core/util/latent_see.h',
'src/core/util/spinlock.h',
'src/core/util/string.h',
'src/core/util/time_precise.h',

3
gRPC-Core.podspec generated

@ -2046,6 +2046,8 @@ Pod::Spec.new do |s|
'src/core/util/json/json_util.h',
'src/core/util/json/json_writer.cc',
'src/core/util/json/json_writer.h',
'src/core/util/latent_see.cc',
'src/core/util/latent_see.h',
'src/core/util/linux/cpu.cc',
'src/core/util/linux/log.cc',
'src/core/util/log.cc',
@ -3369,6 +3371,7 @@ Pod::Spec.new do |s|
'src/core/util/json/json_reader.h',
'src/core/util/json/json_util.h',
'src/core/util/json/json_writer.h',
'src/core/util/latent_see.h',
'src/core/util/spinlock.h',
'src/core/util/string.h',
'src/core/util/time_precise.h',

2
grpc.gemspec generated

@ -1933,6 +1933,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/util/json/json_util.h )
s.files += %w( src/core/util/json/json_writer.cc )
s.files += %w( src/core/util/json/json_writer.h )
s.files += %w( src/core/util/latent_see.cc )
s.files += %w( src/core/util/latent_see.h )
s.files += %w( src/core/util/linux/cpu.cc )
s.files += %w( src/core/util/linux/log.cc )
s.files += %w( src/core/util/log.cc )

@ -836,6 +836,12 @@ extern void gpr_unreachable_code(const char* reason, const char* file,
#endif /* __GPR_WINDOWS */
#endif /* GRPC_ALLOW_EXCEPTIONS */
#ifdef __has_builtin
#define GRPC_HAS_BUILTIN(a) __has_builtin(a)
#else
#define GRPC_HAS_BUILTIN(a) 0
#endif
/* Use GPR_LIKELY only in cases where you are sure that a certain outcome is the
* most likely. Ideally, also collect performance numbers to justify the claim.
*/

2
package.xml generated

@ -1915,6 +1915,8 @@
<file baseinstalldir="/" name="src/core/util/json/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/util/json/json_writer.cc" role="src" />
<file baseinstalldir="/" name="src/core/util/json/json_writer.h" role="src" />
<file baseinstalldir="/" name="src/core/util/latent_see.cc" role="src" />
<file baseinstalldir="/" name="src/core/util/latent_see.h" role="src" />
<file baseinstalldir="/" name="src/core/util/linux/cpu.cc" role="src" />
<file baseinstalldir="/" name="src/core/util/linux/log.cc" role="src" />
<file baseinstalldir="/" name="src/core/util/log.cc" role="src" />

@ -88,6 +88,9 @@ grpc_cc_library(
"absl/functional:any_invocable",
"absl/strings",
],
visibility = [
"@grpc:event_engine_base_hdrs",
],
deps = [
":memory_quota",
"//:event_engine_base_hdrs",
@ -130,6 +133,25 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "latent_see",
srcs = [
"util/latent_see.cc",
],
hdrs = [
"util/latent_see.h",
],
external_deps = [
"absl/log",
"absl/strings",
"absl/types:optional",
],
deps = [
"per_cpu",
"//:gpr",
],
)
grpc_cc_library(
name = "transport_fwd",
hdrs = [
@ -242,6 +264,7 @@ grpc_cc_library(
name = "useful",
hdrs = ["util/useful.h"],
external_deps = [
"absl/log:check",
"absl/strings",
"absl/types:variant",
],
@ -580,9 +603,11 @@ grpc_cc_library(
"construct_destruct",
"context",
"event_engine_context",
"latent_see",
"poll",
"promise_factory",
"ref_counted",
"useful",
"//:event_engine_base_hdrs",
"//:exec_ctx",
"//:gpr",
@ -959,6 +984,7 @@ grpc_cc_library(
"construct_destruct",
"context",
"dump_args",
"latent_see",
"no_destruct",
"poll",
"promise_factory",

@ -58,7 +58,6 @@ namespace grpc_core {
namespace chaotic_good {
void ChaoticGoodClientTransport::Orphan() {
LOG(INFO) << "ChaoticGoodClientTransport::Orphan";
AbortWithError();
ActivityPtr writer;
ActivityPtr reader;

@ -323,9 +323,7 @@ auto ChaoticGoodServerTransport::ReadOneFrame(ChaoticGoodTransport& transport) {
return absl::OkStatus();
});
},
[]() -> absl::Status {
return absl::InternalError("Unexpected cancel frame");
});
[]() -> absl::Status { return absl::OkStatus(); });
}),
Default([frame_header]() {
return absl::InternalError(

@ -25,6 +25,10 @@
#include <grpc/support/port_platform.h>
#ifdef _WIN32
#undef ERROR
#endif
void grpc_tracer_init();
void grpc_tracer_shutdown(void);

@ -21,6 +21,7 @@
#include <CoreFoundation/CoreFoundation.h>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include <grpc/support/cpu.h>
@ -64,9 +65,9 @@ CFEventEngine::~CFEventEngine() {
grpc_core::MutexLock lock(&task_mu_);
if (GRPC_TRACE_FLAG_ENABLED(event_engine)) {
for (auto handle : known_handles_) {
gpr_log(GPR_ERROR,
"CFEventEngine:%p uncleared TaskHandle at shutdown:%s", this,
HandleToString(handle).c_str());
LOG(ERROR) << "CFEventEngine:" << this
<< " uncleared TaskHandle at shutdown:"
<< HandleToString(handle);
}
}
CHECK(GPR_LIKELY(known_handles_.empty()));

@ -35,7 +35,6 @@
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/event_engine/slice_buffer.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include "src/core/lib/debug/trace.h"
@ -451,11 +450,9 @@ PosixEventEngine::~PosixEventEngine() {
grpc_core::MutexLock lock(&mu_);
if (GRPC_TRACE_FLAG_ENABLED(event_engine)) {
for (auto handle : known_handles_) {
gpr_log(GPR_ERROR,
"(event_engine) PosixEventEngine:%p uncleared "
"TaskHandle at "
"shutdown:%s",
this, HandleToString(handle).c_str());
LOG(ERROR) << "(event_engine) PosixEventEngine:" << this
<< " uncleared TaskHandle at shutdown:"
<< HandleToString(handle);
}
}
CHECK(GPR_LIKELY(known_handles_.empty()));

@ -22,10 +22,10 @@
#include <utility>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
@ -102,10 +102,9 @@ void TimerManager::TimerInit(Timer* timer, grpc_core::Timestamp deadline,
if (GRPC_TRACE_FLAG_ENABLED(timer)) {
grpc_core::MutexLock lock(&mu_);
if (shutdown_) {
gpr_log(GPR_ERROR,
"WARNING: TimerManager::%p: scheduling Closure::%p after "
"TimerManager has been shut down.",
this, closure);
LOG(ERROR) << "WARNING: TimerManager::" << this
<< ": scheduling Closure::" << closure
<< " after TimerManager has been shut down.";
}
}
timer_list_->TimerInit(timer, deadline, closure);
@ -120,7 +119,7 @@ void TimerManager::Shutdown() {
grpc_core::MutexLock lock(&mu_);
if (shutdown_) return;
if (GRPC_TRACE_FLAG_ENABLED(timer)) {
gpr_log(GPR_DEBUG, "TimerManager::%p shutting down", this);
VLOG(2) << "TimerManager::" << this << " shutting down";
}
shutdown_ = true;
// Wait on the main loop to exit.
@ -128,7 +127,7 @@ void TimerManager::Shutdown() {
}
main_loop_exit_signal_->WaitForNotification();
if (GRPC_TRACE_FLAG_ENABLED(timer)) {
gpr_log(GPR_DEBUG, "TimerManager::%p shutdown complete", this);
VLOG(2) << "TimerManager::" << this << " shutdown complete";
}
}
@ -146,7 +145,7 @@ void TimerManager::RestartPostFork() {
grpc_core::MutexLock lock(&mu_);
CHECK(GPR_LIKELY(shutdown_));
if (GRPC_TRACE_FLAG_ENABLED(timer)) {
gpr_log(GPR_DEBUG, "TimerManager::%p restarting after shutdown", this);
VLOG(2) << "TimerManager::" << this << " restarting after shutdown";
}
shutdown_ = false;
main_loop_exit_signal_.emplace();

@ -18,6 +18,7 @@
#include "absl/cleanup/cleanup.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
@ -41,8 +42,7 @@ constexpr int kMaxWSABUFCount = 16;
void DumpSliceBuffer(SliceBuffer* buffer, absl::string_view context_string) {
for (size_t i = 0; i < buffer->Count(); i++) {
auto str = buffer->MutableSliceAt(i).as_string_view();
gpr_log(GPR_INFO, "%s: %.*s", context_string.data(), str.length(),
str.data());
LOG(INFO) << context_string << ": " << str;
}
}
@ -160,8 +160,8 @@ bool WindowsEndpoint::Write(absl::AnyInvocable<void(absl::Status)> on_writable,
if (GRPC_TRACE_FLAG_ENABLED(event_engine_endpoint_data)) {
for (size_t i = 0; i < data->Count(); i++) {
auto str = data->RefSlice(i).as_string_view();
gpr_log(GPR_INFO, "WindowsEndpoint::%p WRITE (peer=%s): %.*s", this,
peer_address_string_.c_str(), str.length(), str.data());
LOG(INFO) << "WindowsEndpoint::" << this
<< " WRITE (peer=" << peer_address_string_ << "): " << str;
}
}
CHECK(data->Count() <= UINT_MAX);

@ -218,10 +218,9 @@ WindowsEventEngine::~WindowsEventEngine() {
if (!known_handles_.empty()) {
if (GRPC_TRACE_FLAG_ENABLED(event_engine)) {
for (auto handle : known_handles_) {
gpr_log(GPR_ERROR,
"WindowsEventEngine:%p uncleared TaskHandle at shutdown:%s",
this,
HandleToString<EventEngine::TaskHandle>(handle).c_str());
LOG(ERROR) << "WindowsEventEngine:" << this
<< " uncleared TaskHandle at shutdown:"
<< HandleToString<EventEngine::TaskHandle>(handle);
}
}
// Allow a small grace period for timers to be run before shutting down.

@ -170,6 +170,7 @@ Experiments& ExperimentsSingleton() {
} // namespace
void TestOnlyReloadExperimentsFromConfigVariables() {
ExperimentFlags::TestOnlyClear();
ExperimentsSingleton() = LoadExperimentsFromConfigVariable();
PrintExperimentsList();
}
@ -180,8 +181,35 @@ void LoadTestOnlyExperimentsFromMetadata(
new TestExperiments(experiment_metadata, num_experiments);
}
bool IsExperimentEnabled(size_t experiment_id) {
return ExperimentsSingleton().enabled[experiment_id];
std::atomic<uint64_t>
ExperimentFlags::experiment_flags_[kNumExperimentFlagsWords];
bool ExperimentFlags::LoadFlagsAndCheck(size_t experiment_id) {
static_assert(kNumExperiments < kNumExperimentFlagsWords * kFlagsPerWord,
"kNumExperiments must be less than "
"kNumExperimentFlagsWords*kFlagsPerWord; if this fails then "
"make kNumExperimentFlagsWords bigger.");
const auto& experiments = ExperimentsSingleton();
uint64_t building[kNumExperimentFlagsWords];
for (size_t i = 0; i < kNumExperimentFlagsWords; i++) {
building[i] = kLoadedFlag;
}
for (size_t i = 0; i < kNumExperiments; i++) {
if (!experiments.enabled[i]) continue;
auto bit = i % kFlagsPerWord;
auto word = i / kFlagsPerWord;
building[word] |= 1ull << bit;
}
for (size_t i = 0; i < kNumExperimentFlagsWords; i++) {
experiment_flags_[i].store(building[i], std::memory_order_relaxed);
}
return experiments.enabled[experiment_id];
}
void ExperimentFlags::TestOnlyClear() {
for (size_t i = 0; i < kNumExperimentFlagsWords; i++) {
experiment_flags_[i].store(0, std::memory_order_relaxed);
}
}
bool IsExperimentEnabledInConfiguration(size_t experiment_id) {

@ -18,6 +18,8 @@
#include <stddef.h>
#include <stdint.h>
#include <atomic>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
@ -38,16 +40,68 @@ struct ExperimentMetadata {
};
#ifndef GRPC_EXPERIMENTS_ARE_FINAL
class ExperimentFlags {
public:
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static bool IsExperimentEnabled(
size_t experiment_id) {
auto bit = experiment_id % kFlagsPerWord;
auto word = experiment_id / kFlagsPerWord;
auto cur = experiment_flags_[word].load(std::memory_order_relaxed);
if (cur & (1ull << bit)) return true;
if (cur & kLoadedFlag) return false;
return LoadFlagsAndCheck(experiment_id);
}
template <size_t kExperimentId>
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static bool IsExperimentEnabled() {
auto bit = kExperimentId % kFlagsPerWord;
auto word = kExperimentId / kFlagsPerWord;
auto cur = experiment_flags_[word].load(std::memory_order_relaxed);
if (cur & (1ull << bit)) return true;
if (cur & kLoadedFlag) return false;
return LoadFlagsAndCheck(kExperimentId);
}
static void TestOnlyClear();
private:
static bool LoadFlagsAndCheck(size_t experiment_id);
// We layout experiment flags in groups of 63... each 64 bit word contains
// 63 enablement flags (one per experiment), and the high bit which indicates
// whether the flags have been loaded from the configuration.
// Consequently, with one load, we can tell if the experiment is definitely
// enabled (the bit is set), or definitely disabled (the bit is clear, and the
// loaded flag is set), or if we need to load the flags and re-check.
static constexpr size_t kNumExperimentFlagsWords = 8;
static constexpr size_t kFlagsPerWord = 63;
static constexpr uint64_t kLoadedFlag = 0x8000000000000000ull;
static std::atomic<uint64_t> experiment_flags_[kNumExperimentFlagsWords];
};
// Return true if experiment \a experiment_id is enabled.
// Experiments are numbered by their order in the g_experiment_metadata array
// declared in experiments.h.
bool IsExperimentEnabled(size_t experiment_id);
inline bool IsExperimentEnabled(size_t experiment_id) {
return ExperimentFlags::IsExperimentEnabled(experiment_id);
}
template <size_t kExperimentId>
inline bool IsExperimentEnabled() {
return ExperimentFlags::IsExperimentEnabled<kExperimentId>();
}
// Given a test experiment id, returns true if the test experiment is enabled.
// Test experiments can be loaded using the LoadTestOnlyExperimentsFromMetadata
// method.
bool IsTestExperimentEnabled(size_t experiment_id);
template <size_t kExperimentId>
inline bool IsTestExperimentEnabled() {
return IsTestExperimentEnabled(kExperimentId);
}
// Slow check for if a named experiment is enabled.
// Parses the configuration and looks up the experiment in that, so it does not
// affect any global state, but it does require parsing the configuration every

@ -16,8 +16,6 @@
#include "src/core/lib/experiments/experiments.h"
#include <stdint.h>
#include <grpc/support/port_platform.h>
#ifndef GRPC_EXPERIMENTS_ARE_FINAL
@ -114,8 +112,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -181,8 +177,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, false, true},
};
} // namespace grpc_core
@ -279,8 +274,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -346,8 +339,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, false, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, false, true},
};
} // namespace grpc_core
@ -444,8 +436,6 @@ const char* const description_work_serializer_dispatch =
"callback, instead of running things inline in the first thread that "
"successfully enqueues work.";
const char* const additional_constraints_work_serializer_dispatch = "{}";
const uint8_t required_experiments_work_serializer_dispatch[] = {
static_cast<uint8_t>(grpc_core::kExperimentIdEventEngineClient)};
} // namespace
namespace grpc_core {
@ -511,8 +501,7 @@ const ExperimentMetadata g_experiment_metadata[] = {
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
true},
{"work_serializer_dispatch", description_work_serializer_dispatch,
additional_constraints_work_serializer_dispatch,
required_experiments_work_serializer_dispatch, 1, true, true},
additional_constraints_work_serializer_dispatch, nullptr, 0, true, true},
};
} // namespace grpc_core

@ -193,103 +193,103 @@ enum ExperimentIds {
};
#define GRPC_EXPERIMENT_IS_INCLUDED_CALL_STATUS_OVERRIDE_ON_CANCELLATION
inline bool IsCallStatusOverrideOnCancellationEnabled() {
return IsExperimentEnabled(kExperimentIdCallStatusOverrideOnCancellation);
return IsExperimentEnabled<kExperimentIdCallStatusOverrideOnCancellation>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_CANARY_CLIENT_PRIVACY
inline bool IsCanaryClientPrivacyEnabled() {
return IsExperimentEnabled(kExperimentIdCanaryClientPrivacy);
return IsExperimentEnabled<kExperimentIdCanaryClientPrivacy>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_CLIENT_PRIVACY
inline bool IsClientPrivacyEnabled() {
return IsExperimentEnabled(kExperimentIdClientPrivacy);
return IsExperimentEnabled<kExperimentIdClientPrivacy>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_CLIENT
inline bool IsEventEngineClientEnabled() {
return IsExperimentEnabled(kExperimentIdEventEngineClient);
return IsExperimentEnabled<kExperimentIdEventEngineClient>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_DNS
inline bool IsEventEngineDnsEnabled() {
return IsExperimentEnabled(kExperimentIdEventEngineDns);
return IsExperimentEnabled<kExperimentIdEventEngineDns>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_LISTENER
inline bool IsEventEngineListenerEnabled() {
return IsExperimentEnabled(kExperimentIdEventEngineListener);
return IsExperimentEnabled<kExperimentIdEventEngineListener>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_FREE_LARGE_ALLOCATOR
inline bool IsFreeLargeAllocatorEnabled() {
return IsExperimentEnabled(kExperimentIdFreeLargeAllocator);
return IsExperimentEnabled<kExperimentIdFreeLargeAllocator>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_HTTP2_STATS_FIX
inline bool IsHttp2StatsFixEnabled() {
return IsExperimentEnabled(kExperimentIdHttp2StatsFix);
return IsExperimentEnabled<kExperimentIdHttp2StatsFix>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_KEEPALIVE_FIX
inline bool IsKeepaliveFixEnabled() {
return IsExperimentEnabled(kExperimentIdKeepaliveFix);
return IsExperimentEnabled<kExperimentIdKeepaliveFix>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_KEEPALIVE_SERVER_FIX
inline bool IsKeepaliveServerFixEnabled() {
return IsExperimentEnabled(kExperimentIdKeepaliveServerFix);
return IsExperimentEnabled<kExperimentIdKeepaliveServerFix>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_MAX_PINGS_WO_DATA_THROTTLE
inline bool IsMaxPingsWoDataThrottleEnabled() {
return IsExperimentEnabled(kExperimentIdMaxPingsWoDataThrottle);
return IsExperimentEnabled<kExperimentIdMaxPingsWoDataThrottle>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_MONITORING_EXPERIMENT
inline bool IsMonitoringExperimentEnabled() {
return IsExperimentEnabled(kExperimentIdMonitoringExperiment);
return IsExperimentEnabled<kExperimentIdMonitoringExperiment>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_MULTIPING
inline bool IsMultipingEnabled() {
return IsExperimentEnabled(kExperimentIdMultiping);
return IsExperimentEnabled<kExperimentIdMultiping>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_PEER_STATE_BASED_FRAMING
inline bool IsPeerStateBasedFramingEnabled() {
return IsExperimentEnabled(kExperimentIdPeerStateBasedFraming);
return IsExperimentEnabled<kExperimentIdPeerStateBasedFraming>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW
inline bool IsPickFirstNewEnabled() {
return IsExperimentEnabled(kExperimentIdPickFirstNew);
return IsExperimentEnabled<kExperimentIdPickFirstNew>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_INPROC_TRANSPORT
inline bool IsPromiseBasedInprocTransportEnabled() {
return IsExperimentEnabled(kExperimentIdPromiseBasedInprocTransport);
return IsExperimentEnabled<kExperimentIdPromiseBasedInprocTransport>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_RSTPIT
inline bool IsRstpitEnabled() {
return IsExperimentEnabled(kExperimentIdRstpit);
return IsExperimentEnabled<kExperimentIdRstpit>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_SCHEDULE_CANCELLATION_OVER_WRITE
inline bool IsScheduleCancellationOverWriteEnabled() {
return IsExperimentEnabled(kExperimentIdScheduleCancellationOverWrite);
return IsExperimentEnabled<kExperimentIdScheduleCancellationOverWrite>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_SERVER_PRIVACY
inline bool IsServerPrivacyEnabled() {
return IsExperimentEnabled(kExperimentIdServerPrivacy);
return IsExperimentEnabled<kExperimentIdServerPrivacy>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TCP_FRAME_SIZE_TUNING
inline bool IsTcpFrameSizeTuningEnabled() {
return IsExperimentEnabled(kExperimentIdTcpFrameSizeTuning);
return IsExperimentEnabled<kExperimentIdTcpFrameSizeTuning>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TCP_RCV_LOWAT
inline bool IsTcpRcvLowatEnabled() {
return IsExperimentEnabled(kExperimentIdTcpRcvLowat);
return IsExperimentEnabled<kExperimentIdTcpRcvLowat>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TRACE_RECORD_CALLOPS
inline bool IsTraceRecordCallopsEnabled() {
return IsExperimentEnabled(kExperimentIdTraceRecordCallops);
return IsExperimentEnabled<kExperimentIdTraceRecordCallops>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_UNCONSTRAINED_MAX_QUOTA_BUFFER_SIZE
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() {
return IsExperimentEnabled(kExperimentIdUnconstrainedMaxQuotaBufferSize);
return IsExperimentEnabled<kExperimentIdUnconstrainedMaxQuotaBufferSize>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
inline bool IsWorkSerializerClearsTimeCacheEnabled() {
return IsExperimentEnabled(kExperimentIdWorkSerializerClearsTimeCache);
return IsExperimentEnabled<kExperimentIdWorkSerializerClearsTimeCache>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_DISPATCH
inline bool IsWorkSerializerDispatchEnabled() {
return IsExperimentEnabled(kExperimentIdWorkSerializerDispatch);
return IsExperimentEnabled<kExperimentIdWorkSerializerDispatch>();
}
extern const ExperimentMetadata g_experiment_metadata[kNumExperiments];

@ -111,7 +111,6 @@
- name: work_serializer_clears_time_cache
default: true
- name: work_serializer_dispatch
requires: ["event_engine_client"]
default:
# TODO(ysseung): Not fully tested.
ios: broken

@ -43,6 +43,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/telemetry/stats.h"
#include "src/core/telemetry/stats_data.h"
#include "src/core/util/latent_see.h"
namespace grpc_core {
@ -377,6 +378,8 @@ class WorkSerializer::DispatchingWorkSerializer final
// rate of mutex acquisitions per work item tends towards 1.
CallbackVector incoming_ ABSL_GUARDED_BY(mu_);
GPR_NO_UNIQUE_ADDRESS latent_see::Flow flow_;
#ifndef NDEBUG
static thread_local DispatchingWorkSerializer* running_work_serializer_;
#endif
@ -428,6 +431,8 @@ void WorkSerializer::DispatchingWorkSerializer::Run(
// Implementation of EventEngine::Closure::Run - our actual work loop
void WorkSerializer::DispatchingWorkSerializer::Run() {
GRPC_LATENT_SEE_PARENT_SCOPE("WorkSerializer::Run");
flow_.End();
// TODO(ctiller): remove these when we can deprecate ExecCtx
ApplicationCallbackExecCtx app_exec_ctx;
ExecCtx exec_ctx;
@ -457,6 +462,7 @@ void WorkSerializer::DispatchingWorkSerializer::Run() {
if (processing_.empty() && !Refill()) return;
// There's still work in processing_, so schedule ourselves again on
// EventEngine.
flow_.Begin(GRPC_LATENT_SEE_METADATA("WorkSerializer::Link"));
event_engine_->Run(this);
}

@ -42,6 +42,7 @@
#include "src/core/lib/promise/detail/promise_factory.h"
#include "src/core/lib/promise/detail/status.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/util/latent_see.h"
namespace grpc_core {
@ -545,6 +546,8 @@ class PromiseActivity final
}
void WakeupAsync(WakeupMask) final {
GRPC_LATENT_SEE_INNER_SCOPE("PromiseActivity::WakeupAsync");
wakeup_flow_.Begin(GRPC_LATENT_SEE_METADATA("Activity::Wakeup"));
if (!wakeup_scheduled_.exchange(true, std::memory_order_acq_rel)) {
// Can't safely run, so ask to run later.
this->ScheduleWakeup();
@ -568,6 +571,8 @@ class PromiseActivity final
// In response to Wakeup, run the Promise state machine again until it
// settles. Then check for completion, and if we have completed, call on_done.
void Step() ABSL_LOCKS_EXCLUDED(mu()) {
GRPC_LATENT_SEE_PARENT_SCOPE("PromiseActivity::Step");
wakeup_flow_.End();
// Poll the promise until things settle out under a lock.
mu()->Lock();
if (done_) {
@ -644,6 +649,7 @@ class PromiseActivity final
GPR_NO_UNIQUE_ADDRESS Promise promise;
};
GPR_NO_UNIQUE_ADDRESS PromiseHolder promise_holder_ ABSL_GUARDED_BY(mu());
GPR_NO_UNIQUE_ADDRESS latent_see::Flow wakeup_flow_;
};
} // namespace promise_detail

@ -27,6 +27,7 @@
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/util/latent_see.h"
#ifdef GRPC_MAXIMIZE_THREADYNESS
#include "src/core/lib/gprpp/thd.h" // IWYU pragma: keep
@ -214,6 +215,7 @@ void Party::ForceImmediateRepoll(WakeupMask mask) {
}
void Party::RunLocked() {
GRPC_LATENT_SEE_PARENT_SCOPE("Party::RunLocked");
// If there is a party running, then we don't run it immediately
// but instead add it to the end of the list of parties to run.
// This enables a fairly straightforward batching of work from a
@ -269,6 +271,7 @@ bool Party::RunParty() {
}
bool Party::RunOneParticipant(int i) {
GRPC_LATENT_SEE_INNER_SCOPE("Party::RunOneParticipant");
// If the participant is null, skip.
// This allows participants to complete whilst wakers still exist
// somewhere.

@ -42,6 +42,7 @@
#include "src/core/lib/promise/detail/promise_factory.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/resource_quota/arena.h"
#include "src/core/util/useful.h"
// Two implementations of party synchronization are provided: one using a single
// atomic, the other using a mutex and a set of state variables.
@ -121,9 +122,11 @@ class PartySyncUsingAtomics {
// Now update prev_state to be what we want the CAS to see below.
prev_state &= kRefMask | kLocked | kAllocatedMask;
// For each wakeup bit...
for (size_t i = 0; wakeups != 0; i++, wakeups >>= 1) {
while (wakeups != 0) {
uint64_t t = LowestOneBit(wakeups);
const int i = CountTrailingZeros(t);
wakeups ^= t;
// If the bit is not set, skip.
if ((wakeups & 1) == 0) continue;
if (poll_one_participant(i)) {
const uint64_t allocated_bit = (1u << i << kAllocatedShift);
prev_state &= ~allocated_bit;

@ -126,13 +126,15 @@ class ChannelInit::DependencyTracker {
auto it_a = nodes_.find(a);
auto it_b = nodes_.find(b);
if (it_a == nodes_.end()) {
LOG(ERROR) << "gRPC Filter " << a.name()
<< " was not declared before adding an edge to " << b.name();
GRPC_TRACE_LOG(channel_stack, INFO)
<< "gRPC Filter " << a.name()
<< " was not declared before adding an edge to " << b.name();
return;
}
if (it_b == nodes_.end()) {
LOG(ERROR) << "gRPC Filter " << b.name()
<< " was not declared before adding an edge from " << a.name();
GRPC_TRACE_LOG(channel_stack, INFO)
<< "gRPC Filter " << b.name()
<< " was not declared before adding an edge from " << a.name();
return;
}
auto& node_a = it_a->second;

@ -59,6 +59,7 @@
#include "src/core/lib/transport/metadata.h"
#include "src/core/telemetry/stats.h"
#include "src/core/telemetry/stats_data.h"
#include "src/core/util/latent_see.h"
namespace grpc_core {
@ -129,6 +130,7 @@ ClientCall::ClientCall(grpc_call*, uint32_t, grpc_completion_queue* cq,
grpc_call_error ClientCall::StartBatch(const grpc_op* ops, size_t nops,
void* notify_tag,
bool is_notify_tag_closure) {
GRPC_LATENT_SEE_PARENT_SCOPE("ClientCall::StartBatch");
if (nops == 0) {
EndOpImmediately(cq_, notify_tag, is_notify_tag_closure);
return GRPC_CALL_OK;

@ -0,0 +1,113 @@
// Copyright 2024 gRPC 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
//
// http://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.
#include "src/core/util/latent_see.h"
#ifdef GRPC_ENABLE_LATENT_SEE
#include <chrono>
#include <cstdint>
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
namespace grpc_core {
namespace latent_see {
thread_local std::vector<Log::Event> Log::thread_events_;
thread_local uint64_t Log::thread_id_ = Log::Get().next_thread_id_.fetch_add(1);
std::atomic<uint64_t> Flow::next_flow_id_{1};
std::string Log::GenerateJson() {
std::vector<RecordedEvent> events;
for (auto& fragment : fragments_) {
MutexLock lock(&fragment.mu);
events.insert(events.end(), fragment.events.begin(), fragment.events.end());
}
absl::optional<std::chrono::steady_clock::time_point> start_time;
for (auto& event : events) {
if (!start_time.has_value() || *start_time > event.event.timestamp) {
start_time = event.event.timestamp;
}
}
if (!start_time.has_value()) return "[]";
std::string json = "[\n";
bool first = true;
for (const auto& event : events) {
absl::string_view phase;
bool has_id;
switch (event.event.type) {
case EventType::kBegin:
phase = "B";
has_id = false;
break;
case EventType::kEnd:
phase = "E";
has_id = false;
break;
case EventType::kFlowStart:
phase = "s";
has_id = true;
break;
case EventType::kFlowEnd:
phase = "f";
has_id = true;
break;
case EventType::kMark:
phase = "i";
has_id = false;
break;
}
if (!first) absl::StrAppend(&json, ",\n");
first = false;
absl::StrAppend(&json, "{\"name\": ", event.event.metadata->name,
", \"ph\": \"", phase, "\", \"ts\": ",
std::chrono::duration<double, std::micro>(
event.event.timestamp - *start_time)
.count(),
", \"pid\": 0, \"tid\": ", event.thread_id);
if (has_id) {
absl::StrAppend(&json, ", \"id\": ", event.event.id);
}
if (event.event.type == EventType::kFlowEnd) {
absl::StrAppend(&json, ", \"bp\": \"e\"");
}
absl::StrAppend(&json, ", \"args\": {\"file\": \"",
event.event.metadata->file,
"\", \"line\": ", event.event.metadata->line,
", \"batch\": ", event.batch_id, "}}");
}
absl::StrAppend(&json, "\n]");
return json;
}
void Log::FlushThreadLog() {
auto& thread_events = thread_events_;
if (thread_events.empty()) return;
auto& log = Get();
const auto batch_id =
log.next_batch_id_.fetch_add(1, std::memory_order_relaxed);
auto& fragment = log.fragments_.this_cpu();
const auto thread_id = thread_id_;
{
MutexLock lock(&fragment.mu);
for (auto event : thread_events) {
fragment.events.push_back(RecordedEvent{thread_id, batch_id, event});
}
}
thread_events.clear();
}
} // namespace latent_see
} // namespace grpc_core
#endif

@ -0,0 +1,214 @@
// Copyright 2024 gRPC 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
//
// http://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.
#ifndef GRPC_SRC_CORE_UTIL_LATENT_SEE_H
#define GRPC_SRC_CORE_UTIL_LATENT_SEE_H
#include <grpc/support/port_platform.h>
#ifdef GRPC_ENABLE_LATENT_SEE
#include <chrono>
#include <cstdint>
#include <utility>
#include <vector>
#include "absl/log/log.h"
#include "src/core/lib/gprpp/per_cpu.h"
#include "src/core/lib/gprpp/sync.h"
namespace grpc_core {
namespace latent_see {
struct Metadata {
const char* file;
int line;
const char* name;
};
enum class EventType : uint8_t { kBegin, kEnd, kFlowStart, kFlowEnd, kMark };
class Log {
public:
static void FlushThreadLog();
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static void Append(
const Metadata* metadata, EventType type, uint64_t id) {
thread_events_.push_back(
Event{metadata, std::chrono::steady_clock::now(), id, type});
}
private:
Log() = default;
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION static Log& Get() {
static Log* log = []() {
atexit([] {
LOG(INFO) << "Writing latent_see.json in " << get_current_dir_name();
FILE* f = fopen("latent_see.json", "w");
if (f == nullptr) return;
fprintf(f, "%s", log->GenerateJson().c_str());
fclose(f);
});
return new Log();
}();
return *log;
}
std::string GenerateJson();
struct Event {
const Metadata* metadata;
std::chrono::steady_clock::time_point timestamp;
uint64_t id;
EventType type;
};
struct RecordedEvent {
uint64_t thread_id;
uint64_t batch_id;
Event event;
};
std::atomic<uint64_t> next_thread_id_{1};
std::atomic<uint64_t> next_batch_id_{1};
static thread_local std::vector<Event> thread_events_;
static thread_local uint64_t thread_id_;
struct Fragment {
Mutex mu;
std::vector<RecordedEvent> events ABSL_GUARDED_BY(mu);
};
PerCpu<Fragment> fragments_{PerCpuOptions()};
};
template <bool kFlush>
class Scope {
public:
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION explicit Scope(const Metadata* metadata)
: metadata_(metadata) {
Log::Append(metadata_, EventType::kBegin, 0);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~Scope() {
Log::Append(metadata_, EventType::kEnd, 0);
if (kFlush) Log::FlushThreadLog();
}
Scope(const Scope&) = delete;
Scope& operator=(const Scope&) = delete;
private:
const Metadata* const metadata_;
};
using ParentScope = Scope<true>;
using InnerScope = Scope<false>;
class Flow {
public:
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION Flow() : metadata_(nullptr) {}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION explicit Flow(const Metadata* metadata)
: metadata_(metadata),
id_(next_flow_id_.fetch_add(1, std::memory_order_relaxed)) {
Log::Append(metadata_, EventType::kFlowStart, id_);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION ~Flow() {
if (metadata_ != nullptr) {
Log::Append(metadata_, EventType::kFlowEnd, id_);
}
}
Flow(const Flow&) = delete;
Flow& operator=(const Flow&) = delete;
Flow(Flow&& other) noexcept
: metadata_(std::exchange(other.metadata_, nullptr)), id_(other.id_) {}
Flow& operator=(Flow&& other) noexcept {
if (metadata_ != nullptr) Log::Append(metadata_, EventType::kFlowEnd, id_);
metadata_ = std::exchange(other.metadata_, nullptr);
id_ = other.id_;
return *this;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool is_active() const {
return metadata_ != nullptr;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void End() {
if (metadata_ == nullptr) return;
Log::Append(metadata_, EventType::kFlowEnd, id_);
metadata_ = nullptr;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Begin(const Metadata* metadata) {
if (metadata_ != nullptr) Log::Append(metadata_, EventType::kFlowEnd, id_);
metadata_ = metadata;
if (metadata_ == nullptr) return;
id_ = next_flow_id_.fetch_add(1, std::memory_order_relaxed);
Log::Append(metadata_, EventType::kFlowStart, id_);
}
private:
const Metadata* metadata_;
uint64_t id_;
static std::atomic<uint64_t> next_flow_id_;
};
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline void Mark(const Metadata* md) {
Log::Append(md, EventType::kMark, 0);
}
} // namespace latent_see
} // namespace grpc_core
#define GRPC_LATENT_SEE_METADATA(name) \
[]() { \
static grpc_core::latent_see::Metadata metadata = {__FILE__, __LINE__, \
#name}; \
return &metadata; \
}()
// Parent scope: logs a begin and end event, and flushes the thread log on scope
// exit. Because the flush takes some time it's better to place one parent scope
// at the top of the stack, and use lighter weight scopes within it.
#define GRPC_LATENT_SEE_PARENT_SCOPE(name) \
grpc_core::latent_see::ParentScope latent_see_scope##__LINE__( \
GRPC_LATENT_SEE_METADATA(name))
// Inner scope: logs a begin and end event. Lighter weight than parent scope,
// but does not flush the thread state - so should only be enclosed by a parent
// scope.
#define GRPC_LATENT_SEE_INNER_SCOPE(name) \
grpc_core::latent_see::InnerScope latent_see_scope##__LINE__( \
GRPC_LATENT_SEE_METADATA(name))
// Mark: logs a single event.
// This is not flushed automatically, and so should only be used within a parent
// scope.
#define GRPC_LATENT_SEE_MARK(name) \
grpc_core::latent_see::Mark(GRPC_LATENT_SEE_METADATA(name))
#else // !def(GRPC_ENABLE_LATENT_SEE)
namespace grpc_core {
namespace latent_see {
struct Metadata {};
struct Flow {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION bool is_active() const { return false; }
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void End() {}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION void Begin(Metadata*) {}
};
} // namespace latent_see
} // namespace grpc_core
#define GRPC_LATENT_SEE_METADATA(name) nullptr
#define GRPC_LATENT_SEE_PARENT_SCOPE(name) \
do { \
} while (0)
#define GRPC_LATENT_SEE_INNER_SCOPE(name) \
do { \
} while (0)
#define GRPC_LATENT_SEE_MARK(name) \
do { \
} while (0)
#endif // GRPC_ENABLE_LATENT_SEE
#endif // GRPC_SRC_CORE_UTIL_LATENT_SEE_H

@ -23,6 +23,7 @@
#include <cstddef>
#include "absl/log/check.h"
#include "absl/strings/string_view.h"
#include "absl/types/variant.h"
@ -66,43 +67,76 @@ bool GetBit(T i, size_t n) {
}
namespace useful_detail {
inline constexpr uint32_t HexdigitBitcount(uint32_t x) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t HexdigitBitcount(
uint32_t x) {
return (x - ((x >> 1) & 0x77777777) - ((x >> 2) & 0x33333333) -
((x >> 3) & 0x11111111));
}
} // namespace useful_detail
inline constexpr uint32_t BitCount(uint32_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint32_t i) {
return (((useful_detail::HexdigitBitcount(i) +
(useful_detail::HexdigitBitcount(i) >> 4)) &
0x0f0f0f0f) %
255);
}
inline constexpr uint32_t BitCount(uint64_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint64_t i) {
return BitCount(static_cast<uint32_t>(i)) +
BitCount(static_cast<uint32_t>(i >> 32));
}
inline constexpr uint32_t BitCount(uint16_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint16_t i) {
return BitCount(static_cast<uint32_t>(i));
}
inline constexpr uint32_t BitCount(uint8_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
uint8_t i) {
return BitCount(static_cast<uint32_t>(i));
}
inline constexpr uint32_t BitCount(int64_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int64_t i) {
return BitCount(static_cast<uint64_t>(i));
}
inline constexpr uint32_t BitCount(int32_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int32_t i) {
return BitCount(static_cast<uint32_t>(i));
}
inline constexpr uint32_t BitCount(int16_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int16_t i) {
return BitCount(static_cast<uint16_t>(i));
}
inline constexpr uint32_t BitCount(int8_t i) {
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
int8_t i) {
return BitCount(static_cast<uint8_t>(i));
}
#if GRPC_HAS_BUILTIN(__builtin_ctz)
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
DCHECK_NE(i, 0u); // __builtin_ctz returns undefined behavior for 0
return __builtin_ctz(i);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint64_t i) {
DCHECK_NE(i, 0u); // __builtin_ctz returns undefined behavior for 0
return __builtin_ctzll(i);
}
#else
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint32_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return BitCount((i & -i) - 1);
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t CountTrailingZeros(
uint64_t i) {
DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
return BitCount((i & -i) - 1);
}
#endif
// This function uses operator< to implement a qsort-style comparison, whereby:
// if a is smaller than b, a number smaller than 0 is returned.
// if a is bigger than b, a number greater than 0 is returned.
@ -177,6 +211,23 @@ inline uint32_t RoundUpToPowerOf2(uint32_t v) {
return v;
}
// Return a value with only the lowest bit left on.
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint8_t LowestOneBit(uint8_t x) {
return x & -x;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint16_t LowestOneBit(uint16_t x) {
return x & -x;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint32_t LowestOneBit(uint32_t x) {
return x & -x;
}
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline uint64_t LowestOneBit(uint64_t x) {
return x & -x;
}
} // namespace grpc_core
#define GPR_ARRAY_SIZE(array) (sizeof(array) / sizeof(*(array)))

@ -810,6 +810,7 @@ CORE_SOURCE_FILES = [
'src/core/util/json/json_reader.cc',
'src/core/util/json/json_util.cc',
'src/core/util/json/json_writer.cc',
'src/core/util/latent_see.cc',
'src/core/util/linux/cpu.cc',
'src/core/util/linux/log.cc',
'src/core/util/log.cc',

@ -217,7 +217,9 @@ CLIENT_CALL_TEST(SendInitialMetadataAndReceiveStatusAfterTimeout) {
ExecCtx::Get()->InvalidateNow();
auto now = Timestamp::Now();
EXPECT_GE(now - start, Duration::Seconds(1)) << GRPC_DUMP_ARGS(now, start);
EXPECT_LE(now - start, Duration::Seconds(5)) << GRPC_DUMP_ARGS(now, start);
EXPECT_LE(now - start,
g_yodel_fuzzing ? Duration::Minutes(10) : Duration::Seconds(5))
<< GRPC_DUMP_ARGS(now, start);
WaitForAllPendingWork();
}

@ -0,0 +1,4 @@
test_id: 178
event_engine_actions {
run_delay: 261993005056
}

@ -18,7 +18,7 @@
static void BM_IsExperimentEnabled(benchmark::State& state) {
for (auto _ : state) {
grpc_core::IsMonitoringExperimentEnabled();
benchmark::DoNotOptimize(grpc_core::IsMonitoringExperimentEnabled());
}
}
BENCHMARK(BM_IsExperimentEnabled);

@ -133,19 +133,19 @@ enum ExperimentIds {
};
#define GRPC_EXPERIMENT_IS_INCLUDED_TEST_EXPERIMENT_1
inline bool IsTestExperiment1Enabled() {
return IsTestExperimentEnabled(kExperimentIdTestExperiment1);
return IsTestExperimentEnabled<kExperimentIdTestExperiment1>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TEST_EXPERIMENT_2
inline bool IsTestExperiment2Enabled() {
return IsTestExperimentEnabled(kExperimentIdTestExperiment2);
return IsTestExperimentEnabled<kExperimentIdTestExperiment2>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TEST_EXPERIMENT_3
inline bool IsTestExperiment3Enabled() {
return IsTestExperimentEnabled(kExperimentIdTestExperiment3);
return IsTestExperimentEnabled<kExperimentIdTestExperiment3>();
}
#define GRPC_EXPERIMENT_IS_INCLUDED_TEST_EXPERIMENT_4
inline bool IsTestExperiment4Enabled() {
return IsTestExperimentEnabled(kExperimentIdTestExperiment4);
return IsTestExperimentEnabled<kExperimentIdTestExperiment4>();
}
extern const ExperimentMetadata g_test_experiment_metadata[kNumTestExperiments];

@ -535,3 +535,15 @@ grpc_cc_library(
"//src/core:metrics",
],
)
grpc_cc_library(
name = "passthrough_endpoint",
testonly = True,
srcs = ["passthrough_endpoint.cc"],
hdrs = ["passthrough_endpoint.h"],
external_deps = [
],
deps = [
"//:grpc",
],
)

@ -0,0 +1,131 @@
// Copyright 2024 gRPC 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
//
// http://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.
#include "test/core/test_util/passthrough_endpoint.h"
namespace grpc_event_engine {
namespace experimental {
class PassthroughEndpoint::CallbackHelper {
public:
CallbackHelper(EventEngine* event_engine, bool allow_inline_callbacks)
: event_engine_(allow_inline_callbacks ? nullptr : event_engine) {}
template <typename F>
void AddCallback(F&& callback) {
if (event_engine_ != nullptr) {
event_engine_->Run(std::forward<F>(callback));
} else {
callbacks_.emplace_back(std::forward<F>(callback));
}
}
~CallbackHelper() {
for (auto& callback : callbacks_) {
callback();
}
}
private:
EventEngine* event_engine_;
absl::InlinedVector<absl::AnyInvocable<void()>, 4> callbacks_;
};
PassthroughEndpoint::PassthroughEndpointPair
PassthroughEndpoint::MakePassthroughEndpoint(int client_port, int server_port,
bool allow_inline_callbacks) {
auto send_middle =
grpc_core::MakeRefCounted<PassthroughEndpoint::Middle>(client_port);
auto recv_middle =
grpc_core::MakeRefCounted<PassthroughEndpoint::Middle>(server_port);
auto client = std::unique_ptr<PassthroughEndpoint>(new PassthroughEndpoint(
send_middle, recv_middle, allow_inline_callbacks));
auto server = std::unique_ptr<PassthroughEndpoint>(new PassthroughEndpoint(
recv_middle, send_middle, allow_inline_callbacks));
return {std::move(client), std::move(server)};
}
PassthroughEndpoint::~PassthroughEndpoint() {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
send_middle_->Close(callback_helper);
recv_middle_->Close(callback_helper);
}
bool PassthroughEndpoint::Read(absl::AnyInvocable<void(absl::Status)> on_read,
SliceBuffer* buffer, const ReadArgs*) {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
grpc_core::MutexLock lock(&recv_middle_->mu);
if (recv_middle_->closed) {
callback_helper.AddCallback([on_read = std::move(on_read)]() mutable {
on_read(absl::CancelledError());
});
return false;
}
if (recv_middle_->on_write != nullptr) {
*buffer = std::move(*recv_middle_->write_buffer);
callback_helper.AddCallback(
[on_write = std::move(recv_middle_->on_write)]() mutable {
on_write(absl::OkStatus());
});
recv_middle_->on_write = nullptr;
return true;
}
recv_middle_->read_buffer = buffer;
recv_middle_->on_read = std::move(on_read);
return false;
}
bool PassthroughEndpoint::Write(absl::AnyInvocable<void(absl::Status)> on_write,
SliceBuffer* buffer, const WriteArgs*) {
CallbackHelper callback_helper(event_engine_.get(), allow_inline_callbacks_);
grpc_core::MutexLock lock(&send_middle_->mu);
if (send_middle_->closed) {
callback_helper.AddCallback([on_write = std::move(on_write)]() mutable {
on_write(absl::CancelledError());
});
return false;
}
if (send_middle_->on_read != nullptr) {
*send_middle_->read_buffer = std::move(*buffer);
callback_helper.AddCallback(
[on_read = std::move(send_middle_->on_read)]() mutable {
on_read(absl::OkStatus());
});
send_middle_->on_read = nullptr;
return true;
}
send_middle_->write_buffer = buffer;
send_middle_->on_write = std::move(on_write);
return false;
}
void PassthroughEndpoint::Middle::Close(CallbackHelper& callback_helper) {
grpc_core::MutexLock lock(&mu);
closed = true;
if (on_read != nullptr) {
callback_helper.AddCallback([on_read = std::move(on_read)]() mutable {
on_read(absl::CancelledError());
});
on_read = nullptr;
}
if (on_write != nullptr) {
callback_helper.AddCallback([on_write = std::move(on_write)]() mutable {
on_write(absl::CancelledError());
});
on_write = nullptr;
}
}
} // namespace experimental
} // namespace grpc_event_engine

@ -0,0 +1,95 @@
// Copyright 2024 gRPC 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
//
// http://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.
#ifndef GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H
#define GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H
#include <memory>
#include <grpc/event_engine/event_engine.h>
#include "src/core/lib/event_engine/default_event_engine.h"
#include "src/core/lib/event_engine/tcp_socket_utils.h"
#include "src/core/lib/gprpp/ref_counted.h"
namespace grpc_event_engine {
namespace experimental {
class PassthroughEndpoint final : public EventEngine::Endpoint {
public:
struct PassthroughEndpointPair {
std::unique_ptr<PassthroughEndpoint> client;
std::unique_ptr<PassthroughEndpoint> server;
};
// client_port, server_port are markers that are baked into the peer/local
// addresses for debug information.
// allow_inline_callbacks is a flag that allows the endpoint to call the
// on_read/on_write callbacks inline (but outside any PassthroughEndpoint
// locks)
static PassthroughEndpointPair MakePassthroughEndpoint(
int client_port, int server_port, bool allow_inline_callbacks);
~PassthroughEndpoint() override;
bool Read(absl::AnyInvocable<void(absl::Status)> on_read, SliceBuffer* buffer,
const ReadArgs* args) override;
bool Write(absl::AnyInvocable<void(absl::Status)> on_write,
SliceBuffer* buffer, const WriteArgs* args) override;
const EventEngine::ResolvedAddress& GetPeerAddress() const override {
return recv_middle_->address;
}
const EventEngine::ResolvedAddress& GetLocalAddress() const override {
return send_middle_->address;
}
private:
class CallbackHelper;
struct Middle : public grpc_core::RefCounted<Middle> {
explicit Middle(int port)
: address(URIToResolvedAddress(absl::StrCat("ipv4:127.0.0.1:", port))
.value()) {}
void Close(CallbackHelper& callback_helper);
grpc_core::Mutex mu;
bool closed ABSL_GUARDED_BY(mu) = false;
SliceBuffer* read_buffer ABSL_GUARDED_BY(mu) = nullptr;
absl::AnyInvocable<void(absl::Status)> on_read ABSL_GUARDED_BY(mu) =
nullptr;
SliceBuffer* write_buffer ABSL_GUARDED_BY(mu) = nullptr;
absl::AnyInvocable<void(absl::Status)> on_write ABSL_GUARDED_BY(mu) =
nullptr;
EventEngine::ResolvedAddress address;
};
PassthroughEndpoint(grpc_core::RefCountedPtr<Middle> send_middle,
grpc_core::RefCountedPtr<Middle> recv_middle,
bool allow_inline_callbacks)
: send_middle_(std::move(send_middle)),
recv_middle_(std::move(recv_middle)),
allow_inline_callbacks_(allow_inline_callbacks) {}
grpc_core::RefCountedPtr<Middle> send_middle_;
grpc_core::RefCountedPtr<Middle> recv_middle_;
std::shared_ptr<EventEngine> event_engine_ = GetDefaultEventEngine();
bool allow_inline_callbacks_;
};
} // namespace experimental
} // namespace grpc_event_engine
#endif // GRPC_TEST_CORE_TEST_UTIL_PASSTHROUGH_ENDPOINT_H

@ -0,0 +1,48 @@
# Copyright 2021 gRPC 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
#
# http://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("//bazel:grpc_build_system.bzl", "grpc_package")
load("//test/cpp/microbenchmarks:grpc_benchmark_config.bzl", "grpc_cc_benchmark")
licenses(["notice"])
grpc_package(
name = "test/core/transport/benchmarks",
)
grpc_cc_benchmark(
name = "bm_chaotic_good",
srcs = ["bm_chaotic_good.cc"],
deps = [
"//:grpc",
"//src/core:chaotic_good_client_transport",
"//src/core:chaotic_good_server_transport",
"//src/core:default_event_engine",
"//test/core/test_util:passthrough_endpoint",
"//test/core/transport:call_spine_benchmarks",
],
)
grpc_cc_benchmark(
name = "bm_inproc",
srcs = ["bm_inproc.cc"],
deps = [
"//:grpc",
"//src/core:chaotic_good_client_transport",
"//src/core:chaotic_good_server_transport",
"//src/core:default_event_engine",
"//test/core/test_util:passthrough_endpoint",
"//test/core/transport:call_spine_benchmarks",
],
)

@ -0,0 +1,93 @@
// Copyright 2024 gRPC 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
//
// http://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.
#include <benchmark/benchmark.h>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include <grpc/grpc.h>
#include "src/core/ext/transport/chaotic_good/client_transport.h"
#include "src/core/ext/transport/chaotic_good/server_transport.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "test/core/test_util/passthrough_endpoint.h"
#include "test/core/transport/call_spine_benchmarks.h"
namespace grpc_core {
namespace {
const Slice kTestPath = Slice::FromExternalString("/foo/bar");
class ChaoticGoodTraits {
public:
BenchmarkTransport MakeTransport() {
auto channel_args = CoreConfiguration::Get()
.channel_args_preconditioning()
.PreconditionChannelArgs(nullptr);
auto control = grpc_event_engine::experimental::PassthroughEndpoint::
MakePassthroughEndpoint(1, 2, true);
auto data = grpc_event_engine::experimental::PassthroughEndpoint::
MakePassthroughEndpoint(3, 4, true);
auto client = MakeOrphanable<chaotic_good::ChaoticGoodClientTransport>(
PromiseEndpoint(std::move(control.client), SliceBuffer()),
PromiseEndpoint(std::move(data.client), SliceBuffer()), channel_args,
grpc_event_engine::experimental::GetDefaultEventEngine(), HPackParser(),
HPackCompressor());
auto server = MakeOrphanable<chaotic_good::ChaoticGoodServerTransport>(
channel_args, PromiseEndpoint(std::move(control.server), SliceBuffer()),
PromiseEndpoint(std::move(data.server), SliceBuffer()),
grpc_event_engine::experimental::GetDefaultEventEngine(), HPackParser(),
HPackCompressor());
return {std::move(client), std::move(server)};
}
ClientMetadataHandle MakeClientInitialMetadata() {
auto md = Arena::MakePooled<ClientMetadata>();
md->Set(HttpPathMetadata(), kTestPath.Copy());
return md;
}
ServerMetadataHandle MakeServerInitialMetadata() {
return Arena::MakePooled<ServerMetadata>();
}
MessageHandle MakePayload() { return Arena::MakePooled<Message>(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
auto md = Arena::MakePooled<ServerMetadata>();
return md;
}
};
GRPC_CALL_SPINE_BENCHMARK(TransportFixture<ChaoticGoodTraits>);
} // namespace
} // namespace grpc_core
// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
// and others do not. This allows us to support both modes.
namespace benchmark {
void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
} // namespace benchmark
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
grpc_init();
{
auto ee = grpc_event_engine::experimental::GetDefaultEventEngine();
benchmark::RunTheBenchmarksNamespaced();
}
grpc_shutdown();
return 0;
}

@ -0,0 +1,83 @@
// Copyright 2024 gRPC 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
//
// http://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.
#include <memory>
#include <benchmark/benchmark.h>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include <grpc/grpc.h>
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "test/core/transport/call_spine_benchmarks.h"
namespace grpc_core {
namespace {
const Slice kTestPath = Slice::FromExternalString("/foo/bar");
class InprocTraits {
public:
BenchmarkTransport MakeTransport() {
auto channel_args = CoreConfiguration::Get()
.channel_args_preconditioning()
.PreconditionChannelArgs(nullptr);
auto t = MakeInProcessTransportPair(channel_args);
return {OrphanablePtr<ClientTransport>(
DownCast<ClientTransport*>(t.first.release())),
OrphanablePtr<ServerTransport>(
DownCast<ServerTransport*>(t.second.release()))};
}
ClientMetadataHandle MakeClientInitialMetadata() {
auto md = Arena::MakePooled<ClientMetadata>();
md->Set(HttpPathMetadata(), kTestPath.Copy());
return md;
}
ServerMetadataHandle MakeServerInitialMetadata() {
return Arena::MakePooled<ServerMetadata>();
}
MessageHandle MakePayload() { return Arena::MakePooled<Message>(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
auto md = Arena::MakePooled<ServerMetadata>();
return md;
}
};
GRPC_CALL_SPINE_BENCHMARK(TransportFixture<InprocTraits>);
} // namespace
} // namespace grpc_core
// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
// and others do not. This allows us to support both modes.
namespace benchmark {
void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
} // namespace benchmark
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
grpc_init();
{
auto ee = grpc_event_engine::experimental::GetDefaultEventEngine();
benchmark::RunTheBenchmarksNamespaced();
}
grpc_shutdown();
return 0;
}

@ -27,6 +27,7 @@
#include "src/core/lib/promise/map.h"
#include "src/core/lib/resource_quota/resource_quota.h"
#include "src/core/lib/transport/call_spine.h"
#include "src/core/lib/transport/transport.h"
namespace grpc_core {
@ -219,12 +220,13 @@ void BM_ClientToServerStreaming(benchmark::State& state) {
handler_done.WaitForNotification();
initiator_done.WaitForNotification();
}
call.initiator.SpawnInfallible("done", [&]() {
call.initiator.Cancel();
return Empty{};
});
call.handler.SpawnInfallible("done", [&]() {
call.handler.PushServerTrailingMetadata(
call.initiator.SpawnInfallible("done",
[initiator = call.initiator]() mutable {
initiator.Cancel();
return Empty{};
});
call.handler.SpawnInfallible("done", [handler = call.handler]() mutable {
handler.PushServerTrailingMetadata(
CancelledServerMetadataFromStatus(absl::CancelledError()));
return Empty{};
});
@ -361,6 +363,88 @@ class UnstartedCallDestinationFixture {
traits_->CreateCallDestination(bottom_destination_);
};
// Base class for transports
// Traits should have MakeClientInitialMetadata, MakeServerInitialMetadata,
// MakePayload, MakeServerTrailingMetadata.
// They should also have a MakeTransport returning a BenchmarkTransport.
struct BenchmarkTransport {
OrphanablePtr<ClientTransport> client;
OrphanablePtr<ServerTransport> server;
};
template <class Traits>
class TransportFixture {
public:
TransportFixture() { transport_.server->SetCallDestination(acceptor_); };
BenchmarkCall MakeCall() {
auto arena = arena_allocator_->MakeArena();
arena->SetContext<grpc_event_engine::experimental::EventEngine>(
event_engine_.get());
auto p =
MakeCallPair(traits_.MakeClientInitialMetadata(), std::move(arena));
transport_.client->StartCall(p.handler.StartCall());
auto handler = acceptor_->TakeHandler();
absl::optional<CallHandler> started_handler;
Notification started;
handler.SpawnInfallible("handler_setup", [&]() {
started_handler = handler.StartCall();
started.Notify();
return Empty{};
});
started.WaitForNotification();
CHECK(started_handler.has_value());
return {std::move(p.initiator), std::move(*started_handler)};
}
ServerMetadataHandle MakeServerInitialMetadata() {
return traits_.MakeServerInitialMetadata();
}
MessageHandle MakePayload() { return traits_.MakePayload(); }
ServerMetadataHandle MakeServerTrailingMetadata() {
return traits_.MakeServerTrailingMetadata();
}
private:
class Acceptor : public UnstartedCallDestination {
public:
void StartCall(UnstartedCallHandler handler) override {
MutexLock lock(&mu_);
handler_ = std::move(handler);
}
void Orphaned() override {}
UnstartedCallHandler TakeHandler() {
mu_.LockWhen(absl::Condition(
+[](Acceptor* dest) ABSL_EXCLUSIVE_LOCKS_REQUIRED(dest->mu_) {
return dest->handler_.has_value();
},
this));
auto h = std::move(*handler_);
handler_.reset();
mu_.Unlock();
return h;
}
absl::Mutex mu_;
absl::optional<UnstartedCallHandler> handler_ ABSL_GUARDED_BY(mu_);
};
Traits traits_;
std::shared_ptr<grpc_event_engine::experimental::EventEngine> event_engine_ =
grpc_event_engine::experimental::GetDefaultEventEngine();
RefCountedPtr<CallArenaAllocator> arena_allocator_ =
MakeRefCounted<CallArenaAllocator>(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator(
"test-allocator"),
1024);
RefCountedPtr<Acceptor> acceptor_ = MakeRefCounted<Acceptor>();
BenchmarkTransport transport_ = traits_.MakeTransport();
};
} // namespace grpc_core
// Declare all relevant benchmarks for a given fixture

@ -93,6 +93,144 @@ TEST(UsefulTest, RoundUpToPowerOf2) {
EXPECT_EQ(RoundUpToPowerOf2(8), 8);
}
TEST(UsefulTest, CountTrailingZeros32) {
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(1)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(2)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(3)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(4)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(5)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(6)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(7)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(8)), 3);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(9)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(10)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(11)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(12)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(13)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(14)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(15)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(16)), 4);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(256)), 8);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(65535)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(65536)), 16);
EXPECT_EQ(CountTrailingZeros(static_cast<uint32_t>(0x80000000)), 31);
}
TEST(UsefulTest, CountTrailingZeros64) {
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(1)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(2)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(3)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(4)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(5)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(6)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(7)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(8)), 3);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(9)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(10)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(11)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(12)), 2);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(13)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(14)), 1);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(15)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(16)), 4);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(256)), 8);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(65535)), 0);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(65536)), 16);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x80000000)), 31);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x100000000)), 32);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x1000000000000)), 48);
EXPECT_EQ(CountTrailingZeros(static_cast<uint64_t>(0x8000000000000000)), 63);
}
TEST(UsefulTest, LowestOneBit8) {
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(0)), 0);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(1)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(2)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(3)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(4)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(5)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(6)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(7)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(8)), 8);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(9)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(10)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(11)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(12)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(13)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(14)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(15)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(16)), 16);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(127)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint8_t>(128)), 128);
}
TEST(UsefulTest, LowestOneBit16) {
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(0)), 0);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(1)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(2)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(3)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(4)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(5)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(6)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(7)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(8)), 8);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(9)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(10)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(11)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(12)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(13)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(14)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(15)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(16)), 16);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(32767)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint16_t>(32768)), 32768);
}
TEST(UsefulTest, LowestOneBit32) {
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(0)), 0);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(1)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(2)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(3)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(4)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(5)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(6)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(7)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(8)), 8);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(9)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(10)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(11)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(12)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(13)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(14)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(15)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(16)), 16);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(2147483647)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint32_t>(2147483648)), 2147483648);
}
TEST(UsefulTest, LowestOneBit64) {
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(0)), 0);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(1)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(2)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(3)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(4)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(5)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(6)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(7)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(8)), 8);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(9)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(10)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(11)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(12)), 4);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(13)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(14)), 2);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(15)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(16)), 16);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(9223372036854775807)), 1);
EXPECT_EQ(LowestOneBit(static_cast<uint64_t>(9223372036854775808U)),
9223372036854775808U);
}
} // namespace grpc_core
int main(int argc, char** argv) {

@ -35,6 +35,8 @@ build --define=use_fast_cpp_protos=true
build:opt --compilation_mode=opt
build:opt --copt=-Wframe-larger-than=16384
build:latent_see --copt=-DGRPC_ENABLE_LATENT_SEE
build:dbg --compilation_mode=dbg
# Dynamic link cause issues like: `dyld: malformed mach-o: load commands size (59272) > 32768`

@ -56,13 +56,13 @@ def generate_run_tests_portability_tests(name):
# TODO(https://github.com/grpc/grpc/issues/36751): Replace gcc_8 with gcc_7 once it's fixed.
# ["gcc_7", "", "tools/dockerfile/test/cxx_gcc_7_x64.current_version"],
["gcc_8", "", "tools/dockerfile/test/cxx_gcc_8_x64.current_version"],
["gcc_12", "--cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=20", "tools/dockerfile/test/cxx_gcc_12_x64.current_version"],
["gcc_12_cxx20", "--cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=20", "tools/dockerfile/test/cxx_gcc_12_x64.current_version"],
["gcc10.2_openssl102", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl102_x64.current_version"],
["gcc10.2_openssl111", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl111_x64.current_version"],
["gcc_12_openssl309", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian12_openssl309_x64.current_version"],
["gcc_musl", "", "tools/dockerfile/test/cxx_alpine_x64.current_version"],
["clang_6", "--cmake_configure_extra_args=-DCMAKE_C_COMPILER=clang --cmake_configure_extra_args=-DCMAKE_CXX_COMPILER=clang++", "tools/dockerfile/test/cxx_clang_6_x64.current_version"],
["clang_17", "--cmake_configure_extra_args=-DCMAKE_C_COMPILER=clang --cmake_configure_extra_args=-DCMAKE_CXX_COMPILER=clang++", "tools/dockerfile/test/cxx_clang_17_x64.current_version"],
["clang_17_cxx23", "--cmake_configure_extra_args=-DCMAKE_C_COMPILER=clang --cmake_configure_extra_args=-DCMAKE_CXX_COMPILER=clang++ --cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=23", "tools/dockerfile/test/cxx_clang_17_x64.current_version"],
]
for compiler_name, args, docker_image_version in compiler_configs:

@ -456,7 +456,7 @@ class ExperimentsCompiler(object):
)
print(
"inline bool Is%sEnabled() { return"
" Is%sExperimentEnabled(kExperimentId%s); }"
" Is%sExperimentEnabled<kExperimentId%s>(); }"
% (
SnakeToPascal(exp.name),
"Test" if mode == "test" else "",

@ -1,4 +1,5 @@
include _parallel_compile_patch.py
include _spawn_patch.py
include grpc_version.py
include protoc_deps.py
include protoc_lib_deps.py

@ -0,0 +1,64 @@
# Copyright 2016 gRPC 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
#
# http://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.
"""Patches the spawn() command for windows compilers.
Windows has an 8191 character command line limit, but some compilers
support an @command_file directive where command_file is a file
containing the full command line.
"""
from distutils import ccompiler
import os
import os.path
import shutil
import sys
import tempfile
MAX_COMMAND_LENGTH = 8191
_classic_spawn = ccompiler.CCompiler.spawn
def _commandfile_spawn(self, command, **kwargs):
command_length = sum([len(arg) for arg in command])
if os.name == "nt" and command_length > MAX_COMMAND_LENGTH:
# Even if this command doesn't support the @command_file, it will
# fail as is so we try blindly
print("Command line length exceeded, using command file")
print(" ".join(command))
temporary_directory = tempfile.mkdtemp()
command_filename = os.path.abspath(
os.path.join(temporary_directory, "command")
)
with open(command_filename, "w") as command_file:
escaped_args = [
'"' + arg.replace("\\", "\\\\") + '"' for arg in command[1:]
]
# add each arg on a separate line to avoid hitting the
# "line in command file contains 131071 or more characters" error
# (can happen for extra long link commands)
command_file.write(" \n".join(escaped_args))
modified_command = command[:1] + ["@{}".format(command_filename)]
try:
_classic_spawn(self, modified_command, **kwargs)
finally:
shutil.rmtree(temporary_directory)
else:
_classic_spawn(self, command, **kwargs)
def monkeypatch_spawn():
"""Monkeypatching is dumb, but it's either that or we become maintainers of
something much, much bigger."""
ccompiler.CCompiler.spawn = _commandfile_spawn

@ -37,6 +37,7 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.abspath("."))
import _parallel_compile_patch
import _spawn_patch
import protoc_lib_deps
import grpc_version
@ -48,6 +49,7 @@ else:
_EXT_INIT_SYMBOL = "PyInit__protoc_compiler"
_parallel_compile_patch.monkeypatch_compile_maybe()
_spawn_patch.monkeypatch_spawn()
CLASSIFIERS = [
"Development Status :: 5 - Production/Stable",

@ -2937,6 +2937,8 @@ src/core/util/json/json_util.cc \
src/core/util/json/json_util.h \
src/core/util/json/json_writer.cc \
src/core/util/json/json_writer.h \
src/core/util/latent_see.cc \
src/core/util/latent_see.h \
src/core/util/linux/cpu.cc \
src/core/util/linux/log.cc \
src/core/util/log.cc \

@ -777,6 +777,7 @@ doc/core/epoll-polling-engine.md \
doc/core/grpc-client-server-polling-engine-usage.md \
doc/core/grpc-cq.md \
doc/core/grpc-polling-engines.md \
doc/core/latent_see.md \
doc/core/moving-to-c++.md \
doc/core/pending_api_cleanups.md \
doc/core/transport_explainer.md \

@ -777,6 +777,7 @@ doc/core/epoll-polling-engine.md \
doc/core/grpc-client-server-polling-engine-usage.md \
doc/core/grpc-cq.md \
doc/core/grpc-polling-engines.md \
doc/core/latent_see.md \
doc/core/moving-to-c++.md \
doc/core/pending_api_cleanups.md \
doc/core/transport_explainer.md \
@ -2716,6 +2717,8 @@ src/core/util/json/json_util.cc \
src/core/util/json/json_util.h \
src/core/util/json/json_writer.cc \
src/core/util/json/json_writer.h \
src/core/util/latent_see.cc \
src/core/util/latent_see.h \
src/core/util/linux/cpu.cc \
src/core/util/linux/log.cc \
src/core/util/log.cc \

@ -23,6 +23,28 @@
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
],
"benchmark": true,
"ci_platforms": [
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "bm_chaotic_good",
"platforms": [
"linux",
"posix"
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
@ -111,6 +133,28 @@
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"
],
"benchmark": true,
"ci_platforms": [
"linux",
"posix"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "bm_inproc",
"platforms": [
"linux",
"posix"
],
"uses_polling": false
},
{
"args": [
"--benchmark_min_time=0.001s"

@ -76,7 +76,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/ext/transport/chaotic_good/server_transport.cc",
"./src/core/ext/transport/chttp2/client/chttp2_connector.cc",
"./src/core/ext/transport/chttp2/transport/bin_decoder.cc",
"./src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
"./src/core/ext/transport/chttp2/transport/flow_control.cc",
"./src/core/ext/transport/chttp2/transport/frame_ping.cc",
"./src/core/ext/transport/chttp2/transport/frame_rst_stream.cc",
@ -123,8 +122,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/lib/iomgr/socket_utils_common_posix.cc",
"./src/core/lib/iomgr/tcp_client_cfstream.cc",
"./src/core/lib/iomgr/tcp_client_posix.cc",
"./src/core/lib/iomgr/tcp_posix.cc",
"./src/core/lib/iomgr/tcp_server_posix.cc",
"./src/core/lib/iomgr/tcp_windows.cc",
"./src/core/lib/iomgr/timer_generic.cc",
"./src/core/lib/iomgr/timer_manager.cc",
@ -165,18 +162,6 @@ DEPRECATED_FUNCTION_TEMP_ALLOW_LIST = {
"./src/core/resolver/xds/xds_resolver.cc",
"./src/core/server/server.cc",
"./src/core/server/xds_server_config_fetcher.cc",
"./src/core/tsi/alts/frame_protector/frame_handler.cc",
"./src/core/tsi/alts/handshaker/alts_handshaker_client.cc",
"./src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
"./src/core/tsi/alts/handshaker/transport_security_common_api.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc",
"./src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc",
"./src/core/tsi/fake_transport_security.cc",
"./src/core/tsi/ssl/key_logging/ssl_key_logging.cc",
"./src/core/tsi/ssl_transport_security.cc",
"./src/core/tsi/ssl_transport_security_utils.cc",
"./src/core/util/android/log.cc",
"./src/core/util/linux/log.cc",
"./src/core/util/posix/log.cc",

Loading…
Cancel
Save