pull/37038/head
Craig Tiller 5 months ago
commit 214620d7b0
  1. 4
      BUILD
  2. 36
      CMakeLists.txt
  3. 1
      Makefile
  4. 2
      Package.swift
  5. 72
      build_autogenerated.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 10
      doc/core/latent_see.md
  9. 8
      doc/xds-test-descriptions.md
  10. 2
      gRPC-C++.podspec
  11. 3
      gRPC-Core.podspec
  12. 2
      grpc.gemspec
  13. 2
      package.xml
  14. 24
      src/core/BUILD
  15. 6
      src/core/lib/gprpp/work_serializer.cc
  16. 6
      src/core/lib/promise/activity.h
  17. 3
      src/core/lib/promise/party.cc
  18. 2
      src/core/lib/surface/client_call.cc
  19. 113
      src/core/util/latent_see.cc
  20. 214
      src/core/util/latent_see.h
  21. 16
      src/core/util/useful.h
  22. 1
      src/python/grpcio/grpc_core_dependencies.py
  23. 13
      test/core/transport/call_spine_benchmarks.h
  24. 2
      tools/bazel.rc
  25. 4
      tools/bazelify_tests/test/portability_tests.bzl
  26. 2
      tools/doxygen/Doxyfile.c++.internal
  27. 1
      tools/doxygen/Doxyfile.core
  28. 3
      tools/doxygen/Doxyfile.core.internal

@ -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",
],
)

36
CMakeLists.txt generated

@ -2647,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
@ -3363,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
@ -5441,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
@ -6376,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)
@ -8939,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
@ -8970,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
@ -9194,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)
@ -9518,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
@ -9955,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
@ -9973,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
@ -11063,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
@ -11081,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
@ -14373,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
@ -14385,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
@ -15174,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
@ -15193,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
@ -15261,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
@ -15279,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
@ -18709,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)
@ -18806,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
@ -18824,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
@ -19599,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)
@ -20018,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
@ -20036,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
@ -21005,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)
@ -21506,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)
@ -23389,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)
@ -33157,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",

@ -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
@ -5433,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
@ -5449,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
@ -6615,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
@ -6675,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
@ -6708,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
@ -6739,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
@ -6876,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
@ -6886,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
@ -7228,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
@ -7482,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
@ -7871,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
@ -7906,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
@ -7935,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
@ -7953,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
@ -8691,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
@ -8725,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
@ -8754,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
@ -8772,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
@ -10275,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
@ -10297,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
@ -10326,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
@ -10338,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
@ -10835,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
@ -10871,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
@ -10903,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
@ -10922,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
@ -10968,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
@ -11011,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
@ -11041,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
@ -11059,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
@ -12607,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
@ -12619,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
@ -12670,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
@ -12705,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
@ -12735,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
@ -12753,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
@ -13186,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
@ -13201,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
@ -13376,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
@ -13419,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
@ -13449,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
@ -13467,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
@ -13986,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
@ -13997,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
@ -14295,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
@ -14306,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
@ -15229,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
@ -15245,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
@ -21017,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
@ -21027,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 )

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 = [
@ -581,6 +603,7 @@ grpc_cc_library(
"construct_destruct",
"context",
"event_engine_context",
"latent_see",
"poll",
"promise_factory",
"ref_counted",
@ -961,6 +984,7 @@ grpc_cc_library(
"construct_destruct",
"context",
"dump_args",
"latent_see",
"no_destruct",
"poll",
"promise_factory",

@ -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.

@ -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

@ -114,24 +114,24 @@ GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t BitCount(
}
#if GRPC_HAS_BUILTIN(__builtin_ctz)
GPR_ATTRIBUTE_ALWAYS_INLINE_FUNCTION inline constexpr uint32_t
CountTrailingZeros(uint32_t i) {
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 constexpr uint32_t
CountTrailingZeros(uint64_t 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 constexpr uint32_t
CountTrailingZeros(uint32_t i) {
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 constexpr uint32_t
CountTrailingZeros(uint64_t i) {
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);
}

@ -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',

@ -220,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{};
});

@ -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:

@ -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 \

Loading…
Cancel
Save