diff --git a/BUILD b/BUILD
index e29ba34178b..c0bcb493f12 100644
--- a/BUILD
+++ b/BUILD
@@ -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",
],
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3b638b05e30..8b514a2833a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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)
@@ -8677,6 +8682,7 @@ target_include_directories(bitset_test
target_link_libraries(bitset_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
+ absl::check
)
@@ -8938,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
@@ -8969,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
@@ -9193,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)
@@ -9517,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
@@ -9954,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
@@ -9972,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
@@ -11062,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
@@ -11080,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
@@ -14372,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
@@ -14384,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
@@ -15173,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
@@ -15192,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
@@ -15260,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
@@ -15278,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
@@ -18708,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)
@@ -18805,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
@@ -18823,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
@@ -19598,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)
@@ -20017,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
@@ -20035,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
@@ -21004,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)
@@ -21505,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)
@@ -23388,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)
@@ -30366,6 +30401,7 @@ target_include_directories(table_test
target_link_libraries(table_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
+ absl::check
absl::type_traits
absl::utility
)
@@ -32897,6 +32933,7 @@ target_link_libraries(unique_type_name_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
absl::flat_hash_map
+ absl::check
absl::str_format
)
@@ -33016,6 +33053,7 @@ target_include_directories(useful_test
target_link_libraries(useful_test
${_gRPC_ALLTARGETS_LIBRARIES}
gtest
+ absl::check
)
@@ -33153,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)
diff --git a/Makefile b/Makefile
index 6630151de34..b726a291931 100644
--- a/Makefile
+++ b/Makefile
@@ -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 \
diff --git a/Package.swift b/Package.swift
index 0c6faa4b0c8..d748a579d5c 100644
--- a/Package.swift
+++ b/Package.swift
@@ -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",
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index 47ad422c32e..e15de0ea55c 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -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
@@ -6454,6 +6464,7 @@ targets:
- test/core/gprpp/bitset_test.cc
deps:
- gtest
+ - absl/log:check
uses_polling: false
- name: buffer_list_test
gtest: true
@@ -6614,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
@@ -6674,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
@@ -6707,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
@@ -6738,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
@@ -6875,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
@@ -6885,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
@@ -7227,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
@@ -7481,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
@@ -7870,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
@@ -7905,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
@@ -7934,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
@@ -7952,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
@@ -8690,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
@@ -8724,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
@@ -8753,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
@@ -8771,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
@@ -10274,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
@@ -10296,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
@@ -10325,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
@@ -10337,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
@@ -10834,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
@@ -10870,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
@@ -10902,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
@@ -10921,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
@@ -10967,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
@@ -11010,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
@@ -11040,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
@@ -11058,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
@@ -12606,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
@@ -12618,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
@@ -12669,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
@@ -12704,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
@@ -12734,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
@@ -12752,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
@@ -13185,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
@@ -13200,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
@@ -13375,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
@@ -13418,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
@@ -13448,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
@@ -13466,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
@@ -13985,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
@@ -13996,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
@@ -14294,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
@@ -14305,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
@@ -15228,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
@@ -15244,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
@@ -19730,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
@@ -20930,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
@@ -20966,6 +21037,7 @@ targets:
- test/core/util/useful_test.cc
deps:
- gtest
+ - absl/log:check
uses_polling: false
- name: uuid_v4_test
gtest: true
@@ -21013,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
@@ -21023,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
diff --git a/config.m4 b/config.m4
index 00e36a726b9..942e82b053b 100644
--- a/config.m4
+++ b/config.m4
@@ -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 \
diff --git a/config.w32 b/config.w32
index 56e9bbf62c1..b54524d8e59 100644
--- a/config.w32
+++ b/config.w32
@@ -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 " +
diff --git a/doc/core/latent_see.md b/doc/core/latent_see.md
new file mode 100644
index 00000000000..3003f9bd2ee
--- /dev/null
+++ b/doc/core/latent_see.md
@@ -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.
diff --git a/doc/xds-test-descriptions.md b/doc/xds-test-descriptions.md
index be2b3ff0eb6..f5e26192026 100644
--- a/doc/xds-test-descriptions.md
+++ b/doc/xds-test-descriptions.md
@@ -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
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index bd21f0d9449..58667cbde56 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -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',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 0ec29d02d9a..1008d8ac8d7 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -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',
diff --git a/grpc.gemspec b/grpc.gemspec
index 502209e72cc..d64ac9befe3 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -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 )
diff --git a/package.xml b/package.xml
index 5b27bb11256..63d07ff1f5c 100644
--- a/package.xml
+++ b/package.xml
@@ -1915,6 +1915,8 @@
+
+
diff --git a/src/core/BUILD b/src/core/BUILD
index 81d6af3ee44..f711c07c4e5 100644
--- a/src/core/BUILD
+++ b/src/core/BUILD
@@ -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",
diff --git a/src/core/lib/gprpp/work_serializer.cc b/src/core/lib/gprpp/work_serializer.cc
index 45de57f9ba8..2e2a9488acd 100644
--- a/src/core/lib/gprpp/work_serializer.cc
+++ b/src/core/lib/gprpp/work_serializer.cc
@@ -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);
}
diff --git a/src/core/lib/promise/activity.h b/src/core/lib/promise/activity.h
index 2b90c7cdb4b..715a28c0471 100644
--- a/src/core/lib/promise/activity.h
+++ b/src/core/lib/promise/activity.h
@@ -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
diff --git a/src/core/lib/promise/party.cc b/src/core/lib/promise/party.cc
index 51b54259b08..e6a7b2285fd 100644
--- a/src/core/lib/promise/party.cc
+++ b/src/core/lib/promise/party.cc
@@ -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.
diff --git a/src/core/lib/surface/client_call.cc b/src/core/lib/surface/client_call.cc
index 1d8b42ebbcf..83bf4cfb42a 100644
--- a/src/core/lib/surface/client_call.cc
+++ b/src/core/lib/surface/client_call.cc
@@ -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;
diff --git a/src/core/util/latent_see.cc b/src/core/util/latent_see.cc
new file mode 100644
index 00000000000..cdfaf51b509
--- /dev/null
+++ b/src/core/util/latent_see.cc
@@ -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
+#include
+
+#include "absl/strings/str_cat.h"
+#include "absl/types/optional.h"
+
+namespace grpc_core {
+namespace latent_see {
+
+thread_local std::vector Log::thread_events_;
+thread_local uint64_t Log::thread_id_ = Log::Get().next_thread_id_.fetch_add(1);
+std::atomic Flow::next_flow_id_{1};
+
+std::string Log::GenerateJson() {
+ std::vector events;
+ for (auto& fragment : fragments_) {
+ MutexLock lock(&fragment.mu);
+ events.insert(events.end(), fragment.events.begin(), fragment.events.end());
+ }
+ absl::optional 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(
+ 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
diff --git a/src/core/util/latent_see.h b/src/core/util/latent_see.h
new file mode 100644
index 00000000000..c8e6686690d
--- /dev/null
+++ b/src/core/util/latent_see.h
@@ -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
+
+#ifdef GRPC_ENABLE_LATENT_SEE
+#include
+#include
+#include
+#include
+
+#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 next_thread_id_{1};
+ std::atomic next_batch_id_{1};
+ static thread_local std::vector thread_events_;
+ static thread_local uint64_t thread_id_;
+ struct Fragment {
+ Mutex mu;
+ std::vector events ABSL_GUARDED_BY(mu);
+ };
+ PerCpu fragments_{PerCpuOptions()};
+};
+
+template
+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;
+using InnerScope = Scope;
+
+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 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
diff --git a/src/core/util/useful.h b/src/core/util/useful.h
index 9d8bcb6ff09..f7dadef5201 100644
--- a/src/core/util/useful.h
+++ b/src/core/util/useful.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) {
- DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
+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) {
- DCHECK_NE(i, 0); // __builtin_ctz returns undefined behavior for 0
+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);
}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index f25afdd0126..c46806945a0 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -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',
diff --git a/test/core/transport/call_spine_benchmarks.h b/test/core/transport/call_spine_benchmarks.h
index 47463ac9c76..9c09ef95f87 100644
--- a/test/core/transport/call_spine_benchmarks.h
+++ b/test/core/transport/call_spine_benchmarks.h
@@ -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{};
});
diff --git a/tools/bazel.rc b/tools/bazel.rc
index 3d98df37012..379f6d4c3d2 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -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`
diff --git a/tools/bazelify_tests/test/portability_tests.bzl b/tools/bazelify_tests/test/portability_tests.bzl
index 006d1f48b45..e7852dfb149 100644
--- a/tools/bazelify_tests/test/portability_tests.bzl
+++ b/tools/bazelify_tests/test/portability_tests.bzl
@@ -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:
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a3b4c83cbec..aed08bb8420 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -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 \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 2453f576cb9..3242f05f88b 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -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 \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 1e05cb5fce8..7d92ca90642 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -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 \