From a629c9a03e178b526c46fbffa73687262c7b36b9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 15 Nov 2021 08:23:51 -0800 Subject: [PATCH] Reland resource quota work (#28017) * Check if memory owner available prior to polling it The transport may drop the memory owner during its destruction sequence * tcp_fix * Revert "Revert "New resource quota integration (#27643)" (#28014)" This reverts commit 0ea2c37263a3b8e9b5ebad615e087fa07d03d4e3. * clang-format * fix-path * fix --- BUILD | 34 +- CMakeLists.txt | 193 +-- Makefile | 18 +- build_autogenerated.yaml | 214 ++-- config.m4 | 10 +- config.w32 | 10 +- gRPC-C++.podspec | 40 +- gRPC-Core.podspec | 51 +- grpc.gemspec | 29 +- grpc.gyp | 18 +- .../internal/memory_allocator_impl.h | 32 +- include/grpc/event_engine/memory_allocator.h | 38 +- include/grpc/event_engine/memory_request.h | 57 + package.xml | 29 +- .../google_c2p/google_c2p_resolver.cc | 5 +- .../binder/client/channel_create_impl.cc | 9 +- .../transport/binder/server/binder_server.cc | 4 +- .../chttp2/client/chttp2_connector.cc | 24 +- .../chttp2/client/chttp2_connector.h | 2 - .../chttp2/client/insecure/channel_create.cc | 7 +- .../client/insecure/channel_create_posix.cc | 22 +- .../client/secure/secure_channel_create.cc | 8 +- .../transport/chttp2/server/chttp2_server.cc | 99 +- .../server/insecure/server_chttp2_posix.cc | 20 +- .../chttp2/transport/chttp2_transport.cc | 94 +- .../chttp2/transport/chttp2_transport.h | 3 +- .../chttp2/transport/flow_control.cc | 8 +- .../ext/transport/chttp2/transport/internal.h | 10 +- .../client/secure/cronet_channel_create.cc | 5 +- .../ext/transport/inproc/inproc_transport.cc | 8 +- src/core/lib/channel/channel_stack_builder.cc | 2 - src/core/lib/gpr/tls.h | 6 + src/core/lib/gprpp/cpp_impl_of.h | 45 + src/core/lib/http/httpcli.cc | 47 +- src/core/lib/http/httpcli.h | 26 +- src/core/lib/iomgr/endpoint.h | 1 - src/core/lib/iomgr/endpoint_cfstream.cc | 31 +- src/core/lib/iomgr/endpoint_cfstream.h | 8 +- src/core/lib/iomgr/endpoint_pair_posix.cc | 18 +- src/core/lib/iomgr/endpoint_pair_windows.cc | 19 +- src/core/lib/iomgr/resource_quota.cc | 1106 ----------------- src/core/lib/iomgr/resource_quota.h | 226 ---- src/core/lib/iomgr/tcp_client.cc | 6 +- src/core/lib/iomgr/tcp_client.h | 4 +- src/core/lib/iomgr/tcp_client_cfstream.cc | 10 +- src/core/lib/iomgr/tcp_client_custom.cc | 11 +- src/core/lib/iomgr/tcp_client_posix.cc | 29 +- src/core/lib/iomgr/tcp_client_posix.h | 5 +- src/core/lib/iomgr/tcp_client_windows.cc | 11 +- src/core/lib/iomgr/tcp_custom.cc | 45 +- src/core/lib/iomgr/tcp_custom.h | 1 - src/core/lib/iomgr/tcp_posix.cc | 59 +- src/core/lib/iomgr/tcp_posix.h | 4 +- src/core/lib/iomgr/tcp_server.cc | 10 +- src/core/lib/iomgr/tcp_server.h | 14 +- src/core/lib/iomgr/tcp_server_custom.cc | 20 +- src/core/lib/iomgr/tcp_server_posix.cc | 40 +- src/core/lib/iomgr/tcp_server_utils_posix.h | 37 +- src/core/lib/iomgr/tcp_server_windows.cc | 17 +- src/core/lib/iomgr/tcp_windows.cc | 7 +- src/core/lib/iomgr/tcp_windows.h | 3 +- src/core/lib/promise/activity.cc | 3 +- src/core/lib/resource_quota/api.cc | 102 ++ src/core/lib/resource_quota/api.h | 52 + src/core/lib/resource_quota/memory_quota.cc | 69 +- src/core/lib/resource_quota/memory_quota.h | 102 +- src/core/lib/resource_quota/resource_quota.cc | 10 +- src/core/lib/resource_quota/resource_quota.h | 22 +- src/core/lib/resource_quota/thread_quota.h | 2 + src/core/lib/resource_quota/trace.cc | 19 + .../core/lib/resource_quota/trace.h | 16 +- .../aws_external_account_credentials.cc | 23 +- .../external/external_account_credentials.cc | 19 +- .../url_external_account_credentials.cc | 7 +- .../google_default_credentials.cc | 6 +- .../security/credentials/jwt/jwt_verifier.cc | 10 +- .../credentials/oauth2/oauth2_credentials.cc | 24 +- src/core/lib/surface/channel.cc | 33 +- src/core/lib/surface/channel.h | 12 +- src/core/lib/surface/init.cc | 1 - src/core/lib/surface/lame_client.cc | 9 +- src/core/lib/surface/server.cc | 15 +- src/core/lib/surface/server.h | 5 +- .../health/default_health_check_service.cc | 20 +- src/cpp/thread_manager/thread_manager.cc | 18 +- src/cpp/thread_manager/thread_manager.h | 5 +- src/python/grpcio/grpc_core_dependencies.py | 8 +- test/core/bad_client/bad_client.cc | 8 +- test/core/bad_connection/close_fd_test.cc | 9 +- .../end2end/fixtures/h2_sockpair+trace.cc | 29 +- test/core/end2end/fixtures/h2_sockpair.cc | 29 +- .../end2end/fixtures/h2_sockpair_1byte.cc | 27 +- .../end2end/fixtures/http_proxy_fixture.cc | 17 +- test/core/end2end/fuzzers/api_fuzzer.cc | 23 +- test/core/end2end/fuzzers/client_fuzzer.cc | 21 +- test/core/end2end/fuzzers/server_fuzzer.cc | 13 +- test/core/end2end/generate_tests.bzl | 19 +- test/core/end2end/tests/binary_metadata.cc | 5 + test/core/gprpp/BUILD | 12 + test/core/gprpp/cpp_impl_of_test.cc | 33 + test/core/http/format_request_test.cc | 1 + test/core/http/httpcli_test.cc | 8 +- test/core/http/httpscli_test.cc | 8 +- test/core/iomgr/BUILD | 11 - test/core/iomgr/fd_conservation_posix_test.cc | 1 + .../ios/CFStreamTests/CFStreamClientTests.mm | 16 +- .../CFStreamTests/CFStreamEndpointTests.mm | 8 +- test/core/iomgr/resource_quota_test.cc | 1027 --------------- test/core/iomgr/tcp_client_posix_test.cc | 20 +- test/core/iomgr/tcp_posix_test.cc | 63 +- test/core/iomgr/tcp_server_posix_test.cc | 46 +- .../resource_quota/memory_quota_fuzzer.cc | 12 +- .../memory_quota_stress_test.cc | 9 +- test/core/resource_quota/memory_quota_test.cc | 44 +- .../resource_quota/resource_quota_test.cc | 2 +- test/core/security/secure_endpoint_test.cc | 1 - test/core/security/ssl_server_fuzzer.cc | 6 +- .../surface/concurrent_connectivity_test.cc | 9 +- .../binder/end2end/testing_channel_create.cc | 2 +- .../transport/chttp2/context_list_test.cc | 29 +- .../transport/chttp2/settings_timeout_test.cc | 28 +- test/core/util/BUILD | 2 - test/core/util/mock_endpoint.cc | 6 +- test/core/util/mock_endpoint.h | 3 +- test/core/util/passthru_endpoint.cc | 10 +- test/core/util/port_server_client.cc | 15 +- test/core/util/resource_user_util.cc | 43 - test/core/util/test_tcp_server.cc | 10 +- test/cpp/end2end/client_lb_end2end_test.cc | 5 +- test/cpp/microbenchmarks/bm_call_create.cc | 6 +- .../microbenchmarks/bm_chttp2_transport.cc | 9 +- .../callback_streaming_ping_pong.h | 1 - .../callback_unary_ping_pong.h | 1 - test/cpp/microbenchmarks/fullstack_fixtures.h | 17 +- test/cpp/performance/writes_per_rpc_test.cc | 13 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 29 +- tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 29 +- tools/run_tests/generated/tests.json | 96 +- .../run_tests/sanity/core_banned_functions.py | 4 +- 141 files changed, 1790 insertions(+), 3688 deletions(-) create mode 100644 include/grpc/event_engine/memory_request.h create mode 100644 src/core/lib/gprpp/cpp_impl_of.h delete mode 100644 src/core/lib/iomgr/resource_quota.cc delete mode 100644 src/core/lib/iomgr/resource_quota.h create mode 100644 src/core/lib/resource_quota/api.cc create mode 100644 src/core/lib/resource_quota/api.h create mode 100644 src/core/lib/resource_quota/trace.cc rename test/core/util/resource_user_util.h => src/core/lib/resource_quota/trace.h (58%) create mode 100644 test/core/gprpp/cpp_impl_of_test.cc delete mode 100644 test/core/iomgr/resource_quota_test.cc delete mode 100644 test/core/util/resource_user_util.cc diff --git a/BUILD b/BUILD index 09dc801cbb9..314ccbcb534 100644 --- a/BUILD +++ b/BUILD @@ -191,6 +191,7 @@ GRPC_PUBLIC_EVENT_ENGINE_HDRS = [ "include/grpc/event_engine/event_engine.h", "include/grpc/event_engine/port.h", "include/grpc/event_engine/memory_allocator.h", + "include/grpc/event_engine/memory_request.h", "include/grpc/event_engine/internal/memory_allocator_impl.h", ] @@ -901,6 +902,12 @@ grpc_cc_library( public_hdrs = ["src/core/lib/gprpp/construct_destruct.h"], ) +grpc_cc_library( + name = "cpp_impl_of", + hdrs = ["src/core/lib/gprpp/cpp_impl_of.h"], + language = "c++", +) + grpc_cc_library( name = "gpr_codegen", language = "c++", @@ -1434,6 +1441,7 @@ grpc_cc_library( hdrs = [ "include/grpc/event_engine/internal/memory_allocator_impl.h", "include/grpc/event_engine/memory_allocator.h", + "include/grpc/event_engine/memory_request.h", ], language = "c++", deps = [ @@ -1459,10 +1467,12 @@ grpc_cc_library( "exec_ctx_wakeup_scheduler", "gpr_base", "loop", + "map", "orphanable", "poll", "race", "ref_counted_ptr", + "resource_quota_trace", "seq", "slice_refcount", "useful", @@ -1483,6 +1493,20 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "resource_quota_trace", + srcs = [ + "src/core/lib/resource_quota/trace.cc", + ], + hdrs = [ + "src/core/lib/resource_quota/trace.h", + ], + deps = [ + "gpr_platform", + "grpc_trace", + ], +) + grpc_cc_library( name = "resource_quota", srcs = [ @@ -1492,6 +1516,7 @@ grpc_cc_library( "src/core/lib/resource_quota/resource_quota.h", ], deps = [ + "cpp_impl_of", "gpr_base", "memory_quota", "ref_counted", @@ -1711,7 +1736,6 @@ grpc_cc_library( "src/core/lib/iomgr/resolve_address_custom.cc", "src/core/lib/iomgr/resolve_address_posix.cc", "src/core/lib/iomgr/resolve_address_windows.cc", - "src/core/lib/iomgr/resource_quota.cc", "src/core/lib/iomgr/socket_factory_posix.cc", "src/core/lib/iomgr/socket_mutator.cc", "src/core/lib/iomgr/socket_utils_common_posix.cc", @@ -1747,6 +1771,7 @@ grpc_cc_library( "src/core/lib/iomgr/wakeup_fd_pipe.cc", "src/core/lib/iomgr/wakeup_fd_posix.cc", "src/core/lib/iomgr/work_serializer.cc", + "src/core/lib/resource_quota/api.cc", "src/core/lib/slice/b64.cc", "src/core/lib/slice/percent_encoding.cc", "src/core/lib/slice/slice_api.cc", @@ -1817,6 +1842,7 @@ grpc_cc_library( "src/core/lib/compression/algorithm_metadata.h", "src/core/lib/compression/compression_args.h", "src/core/lib/compression/compression_internal.h", + "src/core/lib/resource_quota/api.h", "src/core/lib/compression/message_compress.h", "src/core/lib/compression/stream_compression.h", "src/core/lib/compression/stream_compression_gzip.h", @@ -1865,7 +1891,6 @@ grpc_cc_library( "src/core/lib/iomgr/python_util.h", "src/core/lib/iomgr/resolve_address.h", "src/core/lib/iomgr/resolve_address_custom.h", - "src/core/lib/iomgr/resource_quota.h", "src/core/lib/iomgr/sockaddr.h", "src/core/lib/iomgr/sockaddr_posix.h", "src/core/lib/iomgr/sockaddr_windows.h", @@ -1980,9 +2005,11 @@ grpc_cc_library( "grpc_codegen", "grpc_trace", "json", + "memory_quota", "orphanable", "ref_counted", "ref_counted_ptr", + "resource_quota", "slice", "slice_refcount", "table", @@ -3571,7 +3598,9 @@ grpc_cc_library( "hpack_encoder_index", "hpack_encoder_table", "match", + "memory_quota", "popularity_count", + "resource_quota_trace", "slice", "slice_refcount", "useful", @@ -3666,6 +3695,7 @@ grpc_cc_library( "grpc_codegen", "grpc_http_filters", "grpc_transport_chttp2", + "memory_quota", "ref_counted", "ref_counted_ptr", "slice", diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a5243dcbf2..d21fed5cbef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -709,7 +709,6 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_c tcp_server_posix_test) endif() add_dependencies(buildtests_c test_core_gpr_time_test) - add_dependencies(buildtests_c test_core_iomgr_resource_quota_test) add_dependencies(buildtests_c test_core_security_credentials_test) add_dependencies(buildtests_c test_core_slice_slice_test) add_dependencies(buildtests_c thd_test) @@ -788,6 +787,7 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_cxx context_list_test) add_dependencies(buildtests_cxx context_test) add_dependencies(buildtests_cxx core_configuration_test) + add_dependencies(buildtests_cxx cpp_impl_of_test) add_dependencies(buildtests_cxx delegating_channel_test) add_dependencies(buildtests_cxx destroy_grpclb_channel_with_active_connect_stress_test) add_dependencies(buildtests_cxx dual_ref_counted_test) @@ -893,6 +893,7 @@ if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx remove_stream_from_stalled_lists_test) endif() + add_dependencies(buildtests_cxx resource_quota_test) add_dependencies(buildtests_cxx retry_throttle_test) add_dependencies(buildtests_cxx rls_end2end_test) add_dependencies(buildtests_cxx rls_lb_config_parser_test) @@ -938,7 +939,6 @@ if(gRPC_BUILD_TESTS) endif() add_dependencies(buildtests_cxx string_ref_test) add_dependencies(buildtests_cxx table_test) - add_dependencies(buildtests_cxx test_core_resource_quota_resource_quota_test) add_dependencies(buildtests_cxx test_cpp_client_credentials_test) add_dependencies(buildtests_cxx test_cpp_server_credentials_test) add_dependencies(buildtests_cxx test_cpp_util_slice_test) @@ -1832,6 +1832,7 @@ add_library(grpc src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/event_engine.cc src/core/lib/event_engine/event_engine_factory.cc + src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/sockaddr.cc src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc @@ -1896,7 +1897,6 @@ add_library(grpc src/core/lib/iomgr/resolve_address_custom.cc src/core/lib/iomgr/resolve_address_posix.cc src/core/lib/iomgr/resolve_address_windows.cc - src/core/lib/iomgr/resource_quota.cc src/core/lib/iomgr/socket_factory_posix.cc src/core/lib/iomgr/socket_mutator.cc src/core/lib/iomgr/socket_utils_common_posix.cc @@ -1936,6 +1936,12 @@ add_library(grpc src/core/lib/json/json_util.cc src/core/lib/json/json_writer.cc src/core/lib/matchers/matchers.cc + src/core/lib/promise/activity.cc + src/core/lib/resource_quota/api.cc + src/core/lib/resource_quota/memory_quota.cc + src/core/lib/resource_quota/resource_quota.cc + src/core/lib/resource_quota/thread_quota.cc + src/core/lib/resource_quota/trace.cc src/core/lib/security/authorization/authorization_policy_provider_vtable.cc src/core/lib/security/authorization/evaluate_args.cc src/core/lib/security/authorization/sdk_server_authz_filter.cc @@ -2128,6 +2134,7 @@ foreach(_hdr include/grpc/event_engine/event_engine.h include/grpc/event_engine/internal/memory_allocator_impl.h include/grpc/event_engine/memory_allocator.h + include/grpc/event_engine/memory_request.h include/grpc/event_engine/port.h include/grpc/fork.h include/grpc/grpc.h @@ -2214,7 +2221,6 @@ add_library(grpc_test_util test/core/util/port_server_client.cc test/core/util/reconnect_server.cc test/core/util/resolve_localhost_ip46.cc - test/core/util/resource_user_util.cc test/core/util/slice_splitter.cc test/core/util/stack_tracer.cc test/core/util/subprocess_posix.cc @@ -2283,7 +2289,6 @@ add_library(grpc_test_util_unsecure test/core/util/port_server_client.cc test/core/util/reconnect_server.cc test/core/util/resolve_localhost_ip46.cc - test/core/util/resource_user_util.cc test/core/util/slice_splitter.cc test/core/util/stack_tracer.cc test/core/util/subprocess_posix.cc @@ -2470,6 +2475,7 @@ add_library(grpc_unsecure src/core/lib/event_engine/channel_args_endpoint_config.cc src/core/lib/event_engine/event_engine.cc src/core/lib/event_engine/event_engine_factory.cc + src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/sockaddr.cc src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc @@ -2533,7 +2539,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/resolve_address_custom.cc src/core/lib/iomgr/resolve_address_posix.cc src/core/lib/iomgr/resolve_address_windows.cc - src/core/lib/iomgr/resource_quota.cc src/core/lib/iomgr/socket_factory_posix.cc src/core/lib/iomgr/socket_mutator.cc src/core/lib/iomgr/socket_utils_common_posix.cc @@ -2572,6 +2577,12 @@ add_library(grpc_unsecure src/core/lib/json/json_reader.cc src/core/lib/json/json_util.cc src/core/lib/json/json_writer.cc + src/core/lib/promise/activity.cc + src/core/lib/resource_quota/api.cc + src/core/lib/resource_quota/memory_quota.cc + src/core/lib/resource_quota/resource_quota.cc + src/core/lib/resource_quota/thread_quota.cc + src/core/lib/resource_quota/trace.cc src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc src/core/lib/slice/b64.cc src/core/lib/slice/percent_encoding.cc @@ -2680,6 +2691,7 @@ foreach(_hdr include/grpc/event_engine/event_engine.h include/grpc/event_engine/internal/memory_allocator_impl.h include/grpc/event_engine/memory_allocator.h + include/grpc/event_engine/memory_request.h include/grpc/event_engine/port.h include/grpc/fork.h include/grpc/grpc.h @@ -5993,6 +6005,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) src/core/lib/iomgr/iomgr_internal.cc src/core/lib/promise/activity.cc src/core/lib/resource_quota/memory_quota.cc + src/core/lib/resource_quota/trace.cc src/core/lib/slice/slice.cc src/core/lib/slice/slice_refcount.cc src/core/lib/slice/slice_string_helpers.cc @@ -7224,33 +7237,6 @@ target_link_libraries(test_core_gpr_time_test ) -endif() -if(gRPC_BUILD_TESTS) - -add_executable(test_core_iomgr_resource_quota_test - test/core/iomgr/resource_quota_test.cc -) - -target_include_directories(test_core_iomgr_resource_quota_test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - ${_gRPC_RE2_INCLUDE_DIR} - ${_gRPC_SSL_INCLUDE_DIR} - ${_gRPC_UPB_GENERATED_DIR} - ${_gRPC_UPB_GRPC_GENERATED_DIR} - ${_gRPC_UPB_INCLUDE_DIR} - ${_gRPC_XXHASH_INCLUDE_DIR} - ${_gRPC_ZLIB_INCLUDE_DIR} -) - -target_link_libraries(test_core_iomgr_resource_quota_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util -) - - endif() if(gRPC_BUILD_TESTS) @@ -9861,6 +9847,40 @@ target_link_libraries(core_configuration_test ) +endif() +if(gRPC_BUILD_TESTS) + +add_executable(cpp_impl_of_test + test/core/gprpp/cpp_impl_of_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(cpp_impl_of_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(cpp_impl_of_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} +) + + endif() if(gRPC_BUILD_TESTS) @@ -12912,6 +12932,7 @@ add_executable(memory_quota_test src/core/lib/iomgr/iomgr_internal.cc src/core/lib/promise/activity.cc src/core/lib/resource_quota/memory_quota.cc + src/core/lib/resource_quota/trace.cc src/core/lib/slice/slice.cc src/core/lib/slice/slice_refcount.cc src/core/lib/slice/slice_string_helpers.cc @@ -14308,6 +14329,59 @@ endif() endif() if(gRPC_BUILD_TESTS) +add_executable(resource_quota_test + src/core/lib/debug/trace.cc + src/core/lib/event_engine/memory_allocator.cc + src/core/lib/iomgr/combiner.cc + src/core/lib/iomgr/error.cc + src/core/lib/iomgr/exec_ctx.cc + src/core/lib/iomgr/executor.cc + src/core/lib/iomgr/iomgr_internal.cc + src/core/lib/promise/activity.cc + src/core/lib/resource_quota/memory_quota.cc + src/core/lib/resource_quota/resource_quota.cc + src/core/lib/resource_quota/thread_quota.cc + src/core/lib/resource_quota/trace.cc + src/core/lib/slice/slice.cc + src/core/lib/slice/slice_refcount.cc + src/core/lib/slice/slice_string_helpers.cc + src/core/lib/slice/static_slice.cc + test/core/resource_quota/resource_quota_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + +target_include_directories(resource_quota_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(resource_quota_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + absl::statusor + absl::variant + gpr +) + + +endif() +if(gRPC_BUILD_TESTS) + add_executable(retry_throttle_test test/core/client_channel/retry_throttle_test.cc third_party/googletest/googletest/src/gtest-all.cc @@ -15654,58 +15728,6 @@ target_link_libraries(table_test ) -endif() -if(gRPC_BUILD_TESTS) - -add_executable(test_core_resource_quota_resource_quota_test - src/core/lib/debug/trace.cc - src/core/lib/event_engine/memory_allocator.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/error.cc - src/core/lib/iomgr/exec_ctx.cc - src/core/lib/iomgr/executor.cc - src/core/lib/iomgr/iomgr_internal.cc - src/core/lib/promise/activity.cc - src/core/lib/resource_quota/memory_quota.cc - src/core/lib/resource_quota/resource_quota.cc - src/core/lib/resource_quota/thread_quota.cc - src/core/lib/slice/slice.cc - src/core/lib/slice/slice_refcount.cc - src/core/lib/slice/slice_string_helpers.cc - src/core/lib/slice/static_slice.cc - test/core/resource_quota/resource_quota_test.cc - third_party/googletest/googletest/src/gtest-all.cc - third_party/googletest/googlemock/src/gmock-all.cc -) - -target_include_directories(test_core_resource_quota_resource_quota_test - PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - ${_gRPC_RE2_INCLUDE_DIR} - ${_gRPC_SSL_INCLUDE_DIR} - ${_gRPC_UPB_GENERATED_DIR} - ${_gRPC_UPB_GRPC_GENERATED_DIR} - ${_gRPC_UPB_INCLUDE_DIR} - ${_gRPC_XXHASH_INCLUDE_DIR} - ${_gRPC_ZLIB_INCLUDE_DIR} - third_party/googletest/googletest/include - third_party/googletest/googletest - third_party/googletest/googlemock/include - third_party/googletest/googlemock - ${_gRPC_PROTO_GENS_DIR} -) - -target_link_libraries(test_core_resource_quota_resource_quota_test - ${_gRPC_PROTOBUF_LIBRARIES} - ${_gRPC_ALLTARGETS_LIBRARIES} - absl::statusor - absl::variant - gpr -) - - endif() if(gRPC_BUILD_TESTS) @@ -16785,7 +16807,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) test/core/util/port_server_client.cc test/core/util/reconnect_server.cc test/core/util/resolve_localhost_ip46.cc - test/core/util/resource_user_util.cc test/core/util/slice_splitter.cc test/core/util/stack_tracer.cc test/core/util/subprocess_posix.cc diff --git a/Makefile b/Makefile index 3ebb7ce9dd4..4d6a9a52a06 100644 --- a/Makefile +++ b/Makefile @@ -1382,6 +1382,7 @@ LIBGRPC_SRC = \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/event_engine.cc \ src/core/lib/event_engine/event_engine_factory.cc \ + src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/sockaddr.cc \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ @@ -1446,7 +1447,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/resolve_address_custom.cc \ src/core/lib/iomgr/resolve_address_posix.cc \ src/core/lib/iomgr/resolve_address_windows.cc \ - src/core/lib/iomgr/resource_quota.cc \ src/core/lib/iomgr/socket_factory_posix.cc \ src/core/lib/iomgr/socket_mutator.cc \ src/core/lib/iomgr/socket_utils_common_posix.cc \ @@ -1486,6 +1486,12 @@ LIBGRPC_SRC = \ src/core/lib/json/json_util.cc \ src/core/lib/json/json_writer.cc \ src/core/lib/matchers/matchers.cc \ + src/core/lib/promise/activity.cc \ + src/core/lib/resource_quota/api.cc \ + src/core/lib/resource_quota/memory_quota.cc \ + src/core/lib/resource_quota/resource_quota.cc \ + src/core/lib/resource_quota/thread_quota.cc \ + src/core/lib/resource_quota/trace.cc \ src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \ src/core/lib/security/authorization/evaluate_args.cc \ src/core/lib/security/authorization/sdk_server_authz_filter.cc \ @@ -1625,6 +1631,7 @@ PUBLIC_HEADERS_C += \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ + include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ @@ -1868,6 +1875,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/event_engine.cc \ src/core/lib/event_engine/event_engine_factory.cc \ + src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/sockaddr.cc \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ @@ -1931,7 +1939,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/resolve_address_custom.cc \ src/core/lib/iomgr/resolve_address_posix.cc \ src/core/lib/iomgr/resolve_address_windows.cc \ - src/core/lib/iomgr/resource_quota.cc \ src/core/lib/iomgr/socket_factory_posix.cc \ src/core/lib/iomgr/socket_mutator.cc \ src/core/lib/iomgr/socket_utils_common_posix.cc \ @@ -1970,6 +1977,12 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/json/json_reader.cc \ src/core/lib/json/json_util.cc \ src/core/lib/json/json_writer.cc \ + src/core/lib/promise/activity.cc \ + src/core/lib/resource_quota/api.cc \ + src/core/lib/resource_quota/memory_quota.cc \ + src/core/lib/resource_quota/resource_quota.cc \ + src/core/lib/resource_quota/thread_quota.cc \ + src/core/lib/resource_quota/trace.cc \ src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc \ src/core/lib/slice/b64.cc \ src/core/lib/slice/percent_encoding.cc \ @@ -2027,6 +2040,7 @@ PUBLIC_HEADERS_C += \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ + include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 6d1ce23d6af..14f759345a8 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -421,6 +421,7 @@ libs: - include/grpc/event_engine/event_engine.h - include/grpc/event_engine/internal/memory_allocator_impl.h - include/grpc/event_engine/memory_allocator.h + - include/grpc/event_engine/memory_request.h - include/grpc/event_engine/port.h - include/grpc/fork.h - include/grpc/grpc.h @@ -756,6 +757,7 @@ libs: - src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/chunked_vector.h + - src/core/lib/gprpp/cpp_impl_of.h - src/core/lib/gprpp/dual_ref_counted.h - src/core/lib/gprpp/match.h - src/core/lib/gprpp/orphanable.h @@ -815,7 +817,6 @@ libs: - src/core/lib/iomgr/python_util.h - src/core/lib/iomgr/resolve_address.h - src/core/lib/iomgr/resolve_address_custom.h - - src/core/lib/iomgr/resource_quota.h - src/core/lib/iomgr/sockaddr.h - src/core/lib/iomgr/sockaddr_posix.h - src/core/lib/iomgr/sockaddr_windows.h @@ -845,6 +846,24 @@ libs: - src/core/lib/json/json.h - src/core/lib/json/json_util.h - src/core/lib/matchers/matchers.h + - src/core/lib/promise/activity.h + - src/core/lib/promise/context.h + - src/core/lib/promise/detail/basic_seq.h + - src/core/lib/promise/detail/promise_factory.h + - src/core/lib/promise/detail/promise_like.h + - src/core/lib/promise/detail/status.h + - src/core/lib/promise/detail/switch.h + - src/core/lib/promise/exec_ctx_wakeup_scheduler.h + - src/core/lib/promise/loop.h + - src/core/lib/promise/map.h + - src/core/lib/promise/poll.h + - src/core/lib/promise/race.h + - src/core/lib/promise/seq.h + - src/core/lib/resource_quota/api.h + - src/core/lib/resource_quota/memory_quota.h + - src/core/lib/resource_quota/resource_quota.h + - src/core/lib/resource_quota/thread_quota.h + - src/core/lib/resource_quota/trace.h - src/core/lib/security/authorization/authorization_engine.h - src/core/lib/security/authorization/authorization_policy_provider.h - src/core/lib/security/authorization/evaluate_args.h @@ -1298,6 +1317,7 @@ libs: - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/event_engine.cc - src/core/lib/event_engine/event_engine_factory.cc + - src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/sockaddr.cc - src/core/lib/http/format_request.cc - src/core/lib/http/httpcli.cc @@ -1362,7 +1382,6 @@ libs: - src/core/lib/iomgr/resolve_address_custom.cc - src/core/lib/iomgr/resolve_address_posix.cc - src/core/lib/iomgr/resolve_address_windows.cc - - src/core/lib/iomgr/resource_quota.cc - src/core/lib/iomgr/socket_factory_posix.cc - src/core/lib/iomgr/socket_mutator.cc - src/core/lib/iomgr/socket_utils_common_posix.cc @@ -1402,6 +1421,12 @@ libs: - src/core/lib/json/json_util.cc - src/core/lib/json/json_writer.cc - src/core/lib/matchers/matchers.cc + - src/core/lib/promise/activity.cc + - src/core/lib/resource_quota/api.cc + - src/core/lib/resource_quota/memory_quota.cc + - src/core/lib/resource_quota/resource_quota.cc + - src/core/lib/resource_quota/thread_quota.cc + - src/core/lib/resource_quota/trace.cc - src/core/lib/security/authorization/authorization_policy_provider_vtable.cc - src/core/lib/security/authorization/evaluate_args.cc - src/core/lib/security/authorization/sdk_server_authz_filter.cc @@ -1572,7 +1597,6 @@ libs: - test/core/util/port_server_client.h - test/core/util/reconnect_server.h - test/core/util/resolve_localhost_ip46.h - - test/core/util/resource_user_util.h - test/core/util/slice_splitter.h - test/core/util/stack_tracer.h - test/core/util/subprocess.h @@ -1594,7 +1618,6 @@ libs: - test/core/util/port_server_client.cc - test/core/util/reconnect_server.cc - test/core/util/resolve_localhost_ip46.cc - - test/core/util/resource_user_util.cc - test/core/util/slice_splitter.cc - test/core/util/stack_tracer.cc - test/core/util/subprocess_posix.cc @@ -1627,7 +1650,6 @@ libs: - test/core/util/port_server_client.h - test/core/util/reconnect_server.h - test/core/util/resolve_localhost_ip46.h - - test/core/util/resource_user_util.h - test/core/util/slice_splitter.h - test/core/util/stack_tracer.h - test/core/util/subprocess.h @@ -1648,7 +1670,6 @@ libs: - test/core/util/port_server_client.cc - test/core/util/reconnect_server.cc - test/core/util/resolve_localhost_ip46.cc - - test/core/util/resource_user_util.cc - test/core/util/slice_splitter.cc - test/core/util/stack_tracer.cc - test/core/util/subprocess_posix.cc @@ -1673,6 +1694,7 @@ libs: - include/grpc/event_engine/event_engine.h - include/grpc/event_engine/internal/memory_allocator_impl.h - include/grpc/event_engine/memory_allocator.h + - include/grpc/event_engine/memory_request.h - include/grpc/event_engine/port.h - include/grpc/fork.h - include/grpc/grpc.h @@ -1808,6 +1830,7 @@ libs: - src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/chunked_vector.h + - src/core/lib/gprpp/cpp_impl_of.h - src/core/lib/gprpp/dual_ref_counted.h - src/core/lib/gprpp/match.h - src/core/lib/gprpp/orphanable.h @@ -1867,7 +1890,6 @@ libs: - src/core/lib/iomgr/python_util.h - src/core/lib/iomgr/resolve_address.h - src/core/lib/iomgr/resolve_address_custom.h - - src/core/lib/iomgr/resource_quota.h - src/core/lib/iomgr/sockaddr.h - src/core/lib/iomgr/sockaddr_posix.h - src/core/lib/iomgr/sockaddr_windows.h @@ -1896,6 +1918,24 @@ libs: - src/core/lib/iomgr/work_serializer.h - src/core/lib/json/json.h - src/core/lib/json/json_util.h + - src/core/lib/promise/activity.h + - src/core/lib/promise/context.h + - src/core/lib/promise/detail/basic_seq.h + - src/core/lib/promise/detail/promise_factory.h + - src/core/lib/promise/detail/promise_like.h + - src/core/lib/promise/detail/status.h + - src/core/lib/promise/detail/switch.h + - src/core/lib/promise/exec_ctx_wakeup_scheduler.h + - src/core/lib/promise/loop.h + - src/core/lib/promise/map.h + - src/core/lib/promise/poll.h + - src/core/lib/promise/race.h + - src/core/lib/promise/seq.h + - src/core/lib/resource_quota/api.h + - src/core/lib/resource_quota/memory_quota.h + - src/core/lib/resource_quota/resource_quota.h + - src/core/lib/resource_quota/thread_quota.h + - src/core/lib/resource_quota/trace.h - src/core/lib/slice/b64.h - src/core/lib/slice/percent_encoding.h - src/core/lib/slice/slice_internal.h @@ -2070,6 +2110,7 @@ libs: - src/core/lib/event_engine/channel_args_endpoint_config.cc - src/core/lib/event_engine/event_engine.cc - src/core/lib/event_engine/event_engine_factory.cc + - src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/sockaddr.cc - src/core/lib/http/format_request.cc - src/core/lib/http/httpcli.cc @@ -2133,7 +2174,6 @@ libs: - src/core/lib/iomgr/resolve_address_custom.cc - src/core/lib/iomgr/resolve_address_posix.cc - src/core/lib/iomgr/resolve_address_windows.cc - - src/core/lib/iomgr/resource_quota.cc - src/core/lib/iomgr/socket_factory_posix.cc - src/core/lib/iomgr/socket_mutator.cc - src/core/lib/iomgr/socket_utils_common_posix.cc @@ -2172,6 +2212,12 @@ libs: - src/core/lib/json/json_reader.cc - src/core/lib/json/json_util.cc - src/core/lib/json/json_writer.cc + - src/core/lib/promise/activity.cc + - src/core/lib/resource_quota/api.cc + - src/core/lib/resource_quota/memory_quota.cc + - src/core/lib/resource_quota/resource_quota.cc + - src/core/lib/resource_quota/thread_quota.cc + - src/core/lib/resource_quota/trace.cc - src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc - src/core/lib/slice/b64.cc - src/core/lib/slice/percent_encoding.cc @@ -3680,10 +3726,12 @@ targets: - src/core/lib/promise/detail/switch.h - src/core/lib/promise/exec_ctx_wakeup_scheduler.h - src/core/lib/promise/loop.h + - src/core/lib/promise/map.h - src/core/lib/promise/poll.h - src/core/lib/promise/race.h - src/core/lib/promise/seq.h - src/core/lib/resource_quota/memory_quota.h + - src/core/lib/resource_quota/trace.h - src/core/lib/slice/slice_internal.h - src/core/lib/slice/slice_refcount.h - src/core/lib/slice/slice_refcount_base.h @@ -3700,6 +3748,7 @@ targets: - src/core/lib/iomgr/iomgr_internal.cc - src/core/lib/promise/activity.cc - src/core/lib/resource_quota/memory_quota.cc + - src/core/lib/resource_quota/trace.cc - src/core/lib/slice/slice.cc - src/core/lib/slice/slice_refcount.cc - src/core/lib/slice/slice_string_helpers.cc @@ -4166,14 +4215,6 @@ targets: deps: - grpc_test_util uses_polling: false -- name: test_core_iomgr_resource_quota_test - build: test - language: c - headers: [] - src: - - test/core/iomgr/resource_quota_test.cc - deps: - - grpc_test_util - name: test_core_security_credentials_test build: test language: c @@ -5396,6 +5437,16 @@ targets: - absl/types:optional - upb uses_polling: false +- name: cpp_impl_of_test + gtest: true + build: test + language: c++ + headers: + - src/core/lib/gprpp/cpp_impl_of.h + src: + - test/core/gprpp/cpp_impl_of_test.cc + deps: [] + uses_polling: false - name: delegating_channel_test gtest: true build: test @@ -6750,10 +6801,12 @@ targets: - src/core/lib/promise/detail/switch.h - src/core/lib/promise/exec_ctx_wakeup_scheduler.h - src/core/lib/promise/loop.h + - src/core/lib/promise/map.h - src/core/lib/promise/poll.h - src/core/lib/promise/race.h - src/core/lib/promise/seq.h - src/core/lib/resource_quota/memory_quota.h + - src/core/lib/resource_quota/trace.h - src/core/lib/slice/slice_internal.h - src/core/lib/slice/slice_refcount.h - src/core/lib/slice/slice_refcount_base.h @@ -6771,6 +6824,7 @@ targets: - src/core/lib/iomgr/iomgr_internal.cc - src/core/lib/promise/activity.cc - src/core/lib/resource_quota/memory_quota.cc + - src/core/lib/resource_quota/trace.cc - src/core/lib/slice/slice.cc - src/core/lib/slice/slice_refcount.cc - src/core/lib/slice/slice_string_helpers.cc @@ -7440,6 +7494,71 @@ targets: - linux - posix - mac +- name: resource_quota_test + gtest: true + build: test + language: c++ + headers: + - src/core/lib/debug/trace.h + - src/core/lib/gprpp/atomic_utils.h + - src/core/lib/gprpp/cpp_impl_of.h + - src/core/lib/gprpp/dual_ref_counted.h + - src/core/lib/gprpp/orphanable.h + - src/core/lib/gprpp/ref_counted.h + - src/core/lib/gprpp/ref_counted_ptr.h + - src/core/lib/iomgr/closure.h + - src/core/lib/iomgr/combiner.h + - src/core/lib/iomgr/error.h + - src/core/lib/iomgr/error_internal.h + - src/core/lib/iomgr/exec_ctx.h + - src/core/lib/iomgr/executor.h + - src/core/lib/iomgr/iomgr_internal.h + - src/core/lib/promise/activity.h + - src/core/lib/promise/context.h + - src/core/lib/promise/detail/basic_seq.h + - src/core/lib/promise/detail/promise_factory.h + - src/core/lib/promise/detail/promise_like.h + - src/core/lib/promise/detail/status.h + - src/core/lib/promise/detail/switch.h + - src/core/lib/promise/exec_ctx_wakeup_scheduler.h + - src/core/lib/promise/loop.h + - src/core/lib/promise/map.h + - src/core/lib/promise/poll.h + - src/core/lib/promise/race.h + - src/core/lib/promise/seq.h + - src/core/lib/resource_quota/memory_quota.h + - src/core/lib/resource_quota/resource_quota.h + - src/core/lib/resource_quota/thread_quota.h + - src/core/lib/resource_quota/trace.h + - src/core/lib/slice/slice_internal.h + - src/core/lib/slice/slice_refcount.h + - src/core/lib/slice/slice_refcount_base.h + - src/core/lib/slice/slice_string_helpers.h + - src/core/lib/slice/slice_utils.h + - src/core/lib/slice/static_slice.h + src: + - src/core/lib/debug/trace.cc + - src/core/lib/event_engine/memory_allocator.cc + - src/core/lib/iomgr/combiner.cc + - src/core/lib/iomgr/error.cc + - src/core/lib/iomgr/exec_ctx.cc + - src/core/lib/iomgr/executor.cc + - src/core/lib/iomgr/iomgr_internal.cc + - src/core/lib/promise/activity.cc + - src/core/lib/resource_quota/memory_quota.cc + - src/core/lib/resource_quota/resource_quota.cc + - src/core/lib/resource_quota/thread_quota.cc + - src/core/lib/resource_quota/trace.cc + - src/core/lib/slice/slice.cc + - src/core/lib/slice/slice_refcount.cc + - src/core/lib/slice/slice_string_helpers.cc + - src/core/lib/slice/static_slice.cc + - test/core/resource_quota/resource_quota_test.cc + deps: + - absl/status:statusor + - absl/types:variant + - gpr + uses_polling: false - name: retry_throttle_test gtest: true build: test @@ -7867,67 +7986,6 @@ targets: - absl/types:optional - absl/utility:utility uses_polling: false -- name: test_core_resource_quota_resource_quota_test - gtest: true - build: test - language: c++ - headers: - - src/core/lib/debug/trace.h - - src/core/lib/gprpp/atomic_utils.h - - src/core/lib/gprpp/dual_ref_counted.h - - src/core/lib/gprpp/orphanable.h - - src/core/lib/gprpp/ref_counted.h - - src/core/lib/gprpp/ref_counted_ptr.h - - src/core/lib/iomgr/closure.h - - src/core/lib/iomgr/combiner.h - - src/core/lib/iomgr/error.h - - src/core/lib/iomgr/error_internal.h - - src/core/lib/iomgr/exec_ctx.h - - src/core/lib/iomgr/executor.h - - src/core/lib/iomgr/iomgr_internal.h - - src/core/lib/promise/activity.h - - src/core/lib/promise/context.h - - src/core/lib/promise/detail/basic_seq.h - - src/core/lib/promise/detail/promise_factory.h - - src/core/lib/promise/detail/promise_like.h - - src/core/lib/promise/detail/status.h - - src/core/lib/promise/detail/switch.h - - src/core/lib/promise/exec_ctx_wakeup_scheduler.h - - src/core/lib/promise/loop.h - - src/core/lib/promise/poll.h - - src/core/lib/promise/race.h - - src/core/lib/promise/seq.h - - src/core/lib/resource_quota/memory_quota.h - - src/core/lib/resource_quota/resource_quota.h - - src/core/lib/resource_quota/thread_quota.h - - src/core/lib/slice/slice_internal.h - - src/core/lib/slice/slice_refcount.h - - src/core/lib/slice/slice_refcount_base.h - - src/core/lib/slice/slice_string_helpers.h - - src/core/lib/slice/slice_utils.h - - src/core/lib/slice/static_slice.h - src: - - src/core/lib/debug/trace.cc - - src/core/lib/event_engine/memory_allocator.cc - - src/core/lib/iomgr/combiner.cc - - src/core/lib/iomgr/error.cc - - src/core/lib/iomgr/exec_ctx.cc - - src/core/lib/iomgr/executor.cc - - src/core/lib/iomgr/iomgr_internal.cc - - src/core/lib/promise/activity.cc - - src/core/lib/resource_quota/memory_quota.cc - - src/core/lib/resource_quota/resource_quota.cc - - src/core/lib/resource_quota/thread_quota.cc - - src/core/lib/slice/slice.cc - - src/core/lib/slice/slice_refcount.cc - - src/core/lib/slice/slice_string_helpers.cc - - src/core/lib/slice/static_slice.cc - - test/core/resource_quota/resource_quota_test.cc - deps: - - absl/status:statusor - - absl/types:variant - - gpr - uses_polling: false - name: test_cpp_client_credentials_test gtest: true build: test @@ -8492,7 +8550,6 @@ targets: - test/core/util/port_server_client.h - test/core/util/reconnect_server.h - test/core/util/resolve_localhost_ip46.h - - test/core/util/resource_user_util.h - test/core/util/slice_splitter.h - test/core/util/stack_tracer.h - test/core/util/subprocess.h @@ -8516,7 +8573,6 @@ targets: - test/core/util/port_server_client.cc - test/core/util/reconnect_server.cc - test/core/util/resolve_localhost_ip46.cc - - test/core/util/resource_user_util.cc - test/core/util/slice_splitter.cc - test/core/util/stack_tracer.cc - test/core/util/subprocess_posix.cc diff --git a/config.m4 b/config.m4 index 9420e2ac2f0..a9440bf37a5 100644 --- a/config.m4 +++ b/config.m4 @@ -390,6 +390,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/event_engine/channel_args_endpoint_config.cc \ src/core/lib/event_engine/event_engine.cc \ src/core/lib/event_engine/event_engine_factory.cc \ + src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/sockaddr.cc \ src/core/lib/gpr/alloc.cc \ src/core/lib/gpr/atm.cc \ @@ -497,7 +498,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/resolve_address_custom.cc \ src/core/lib/iomgr/resolve_address_posix.cc \ src/core/lib/iomgr/resolve_address_windows.cc \ - src/core/lib/iomgr/resource_quota.cc \ src/core/lib/iomgr/socket_factory_posix.cc \ src/core/lib/iomgr/socket_mutator.cc \ src/core/lib/iomgr/socket_utils_common_posix.cc \ @@ -539,6 +539,12 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/matchers/matchers.cc \ src/core/lib/profiling/basic_timers.cc \ src/core/lib/profiling/stap_timers.cc \ + src/core/lib/promise/activity.cc \ + src/core/lib/resource_quota/api.cc \ + src/core/lib/resource_quota/memory_quota.cc \ + src/core/lib/resource_quota/resource_quota.cc \ + src/core/lib/resource_quota/thread_quota.cc \ + src/core/lib/resource_quota/trace.cc \ src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \ src/core/lib/security/authorization/evaluate_args.cc \ src/core/lib/security/authorization/sdk_server_authz_filter.cc \ @@ -1204,6 +1210,8 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/matchers) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/profiling) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/promise) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/resource_quota) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/authorization) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/context) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials) diff --git a/config.w32 b/config.w32 index 9c82222898f..fb671f179f5 100644 --- a/config.w32 +++ b/config.w32 @@ -356,6 +356,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\event_engine\\channel_args_endpoint_config.cc " + "src\\core\\lib\\event_engine\\event_engine.cc " + "src\\core\\lib\\event_engine\\event_engine_factory.cc " + + "src\\core\\lib\\event_engine\\memory_allocator.cc " + "src\\core\\lib\\event_engine\\sockaddr.cc " + "src\\core\\lib\\gpr\\alloc.cc " + "src\\core\\lib\\gpr\\atm.cc " + @@ -463,7 +464,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\resolve_address_custom.cc " + "src\\core\\lib\\iomgr\\resolve_address_posix.cc " + "src\\core\\lib\\iomgr\\resolve_address_windows.cc " + - "src\\core\\lib\\iomgr\\resource_quota.cc " + "src\\core\\lib\\iomgr\\socket_factory_posix.cc " + "src\\core\\lib\\iomgr\\socket_mutator.cc " + "src\\core\\lib\\iomgr\\socket_utils_common_posix.cc " + @@ -505,6 +505,12 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\matchers\\matchers.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + "src\\core\\lib\\profiling\\stap_timers.cc " + + "src\\core\\lib\\promise\\activity.cc " + + "src\\core\\lib\\resource_quota\\api.cc " + + "src\\core\\lib\\resource_quota\\memory_quota.cc " + + "src\\core\\lib\\resource_quota\\resource_quota.cc " + + "src\\core\\lib\\resource_quota\\thread_quota.cc " + + "src\\core\\lib\\resource_quota\\trace.cc " + "src\\core\\lib\\security\\authorization\\authorization_policy_provider_vtable.cc " + "src\\core\\lib\\security\\authorization\\evaluate_args.cc " + "src\\core\\lib\\security\\authorization\\sdk_server_authz_filter.cc " + @@ -1308,6 +1314,8 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\matchers"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\profiling"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\promise"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\resource_quota"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\authorization"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\context"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 260efc2bdf4..cd196de9df2 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -599,6 +599,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/bitset.h', 'src/core/lib/gprpp/chunked_vector.h', 'src/core/lib/gprpp/construct_destruct.h', + 'src/core/lib/gprpp/cpp_impl_of.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', @@ -674,7 +675,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/python_util.h', 'src/core/lib/iomgr/resolve_address.h', 'src/core/lib/iomgr/resolve_address_custom.h', - 'src/core/lib/iomgr/resource_quota.h', 'src/core/lib/iomgr/sockaddr.h', 'src/core/lib/iomgr/sockaddr_posix.h', 'src/core/lib/iomgr/sockaddr_windows.h', @@ -705,6 +705,24 @@ Pod::Spec.new do |s| 'src/core/lib/json/json_util.h', 'src/core/lib/matchers/matchers.h', 'src/core/lib/profiling/timers.h', + 'src/core/lib/promise/activity.h', + 'src/core/lib/promise/context.h', + 'src/core/lib/promise/detail/basic_seq.h', + 'src/core/lib/promise/detail/promise_factory.h', + 'src/core/lib/promise/detail/promise_like.h', + 'src/core/lib/promise/detail/status.h', + 'src/core/lib/promise/detail/switch.h', + 'src/core/lib/promise/exec_ctx_wakeup_scheduler.h', + 'src/core/lib/promise/loop.h', + 'src/core/lib/promise/map.h', + 'src/core/lib/promise/poll.h', + 'src/core/lib/promise/race.h', + 'src/core/lib/promise/seq.h', + 'src/core/lib/resource_quota/api.h', + 'src/core/lib/resource_quota/memory_quota.h', + 'src/core/lib/resource_quota/resource_quota.h', + 'src/core/lib/resource_quota/thread_quota.h', + 'src/core/lib/resource_quota/trace.h', 'src/core/lib/security/authorization/authorization_engine.h', 'src/core/lib/security/authorization/authorization_policy_provider.h', 'src/core/lib/security/authorization/evaluate_args.h', @@ -1292,6 +1310,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/bitset.h', 'src/core/lib/gprpp/chunked_vector.h', 'src/core/lib/gprpp/construct_destruct.h', + 'src/core/lib/gprpp/cpp_impl_of.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', @@ -1367,7 +1386,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/python_util.h', 'src/core/lib/iomgr/resolve_address.h', 'src/core/lib/iomgr/resolve_address_custom.h', - 'src/core/lib/iomgr/resource_quota.h', 'src/core/lib/iomgr/sockaddr.h', 'src/core/lib/iomgr/sockaddr_posix.h', 'src/core/lib/iomgr/sockaddr_windows.h', @@ -1398,6 +1416,24 @@ Pod::Spec.new do |s| 'src/core/lib/json/json_util.h', 'src/core/lib/matchers/matchers.h', 'src/core/lib/profiling/timers.h', + 'src/core/lib/promise/activity.h', + 'src/core/lib/promise/context.h', + 'src/core/lib/promise/detail/basic_seq.h', + 'src/core/lib/promise/detail/promise_factory.h', + 'src/core/lib/promise/detail/promise_like.h', + 'src/core/lib/promise/detail/status.h', + 'src/core/lib/promise/detail/switch.h', + 'src/core/lib/promise/exec_ctx_wakeup_scheduler.h', + 'src/core/lib/promise/loop.h', + 'src/core/lib/promise/map.h', + 'src/core/lib/promise/poll.h', + 'src/core/lib/promise/race.h', + 'src/core/lib/promise/seq.h', + 'src/core/lib/resource_quota/api.h', + 'src/core/lib/resource_quota/memory_quota.h', + 'src/core/lib/resource_quota/resource_quota.h', + 'src/core/lib/resource_quota/thread_quota.h', + 'src/core/lib/resource_quota/trace.h', 'src/core/lib/security/authorization/authorization_engine.h', 'src/core/lib/security/authorization/authorization_policy_provider.h', 'src/core/lib/security/authorization/evaluate_args.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1f116b4e437..1c4f9b6888c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -111,6 +111,7 @@ Pod::Spec.new do |s| 'include/grpc/event_engine/event_engine.h', 'include/grpc/event_engine/internal/memory_allocator_impl.h', 'include/grpc/event_engine/memory_allocator.h', + 'include/grpc/event_engine/memory_request.h', 'include/grpc/event_engine/port.h', 'include/grpc/fork.h', 'include/grpc/grpc.h', @@ -871,6 +872,7 @@ Pod::Spec.new do |s| 'src/core/lib/event_engine/event_engine.cc', 'src/core/lib/event_engine/event_engine_factory.cc', 'src/core/lib/event_engine/event_engine_factory.h', + 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/sockaddr.cc', 'src/core/lib/event_engine/sockaddr.h', 'src/core/lib/gpr/alloc.cc', @@ -920,6 +922,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/bitset.h', 'src/core/lib/gprpp/chunked_vector.h', 'src/core/lib/gprpp/construct_destruct.h', + 'src/core/lib/gprpp/cpp_impl_of.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.cc', @@ -1069,8 +1072,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/resolve_address_custom.h', 'src/core/lib/iomgr/resolve_address_posix.cc', 'src/core/lib/iomgr/resolve_address_windows.cc', - 'src/core/lib/iomgr/resource_quota.cc', - 'src/core/lib/iomgr/resource_quota.h', 'src/core/lib/iomgr/sockaddr.h', 'src/core/lib/iomgr/sockaddr_posix.h', 'src/core/lib/iomgr/sockaddr_windows.h', @@ -1142,6 +1143,30 @@ Pod::Spec.new do |s| 'src/core/lib/profiling/basic_timers.cc', 'src/core/lib/profiling/stap_timers.cc', 'src/core/lib/profiling/timers.h', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/promise/activity.h', + 'src/core/lib/promise/context.h', + 'src/core/lib/promise/detail/basic_seq.h', + 'src/core/lib/promise/detail/promise_factory.h', + 'src/core/lib/promise/detail/promise_like.h', + 'src/core/lib/promise/detail/status.h', + 'src/core/lib/promise/detail/switch.h', + 'src/core/lib/promise/exec_ctx_wakeup_scheduler.h', + 'src/core/lib/promise/loop.h', + 'src/core/lib/promise/map.h', + 'src/core/lib/promise/poll.h', + 'src/core/lib/promise/race.h', + 'src/core/lib/promise/seq.h', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/api.h', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/memory_quota.h', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/resource_quota.h', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/thread_quota.h', + 'src/core/lib/resource_quota/trace.cc', + 'src/core/lib/resource_quota/trace.h', 'src/core/lib/security/authorization/authorization_engine.h', 'src/core/lib/security/authorization/authorization_policy_provider.h', 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', @@ -1809,6 +1834,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/bitset.h', 'src/core/lib/gprpp/chunked_vector.h', 'src/core/lib/gprpp/construct_destruct.h', + 'src/core/lib/gprpp/cpp_impl_of.h', 'src/core/lib/gprpp/debug_location.h', 'src/core/lib/gprpp/dual_ref_counted.h', 'src/core/lib/gprpp/examine_stack.h', @@ -1884,7 +1910,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/python_util.h', 'src/core/lib/iomgr/resolve_address.h', 'src/core/lib/iomgr/resolve_address_custom.h', - 'src/core/lib/iomgr/resource_quota.h', 'src/core/lib/iomgr/sockaddr.h', 'src/core/lib/iomgr/sockaddr_posix.h', 'src/core/lib/iomgr/sockaddr_windows.h', @@ -1915,6 +1940,24 @@ Pod::Spec.new do |s| 'src/core/lib/json/json_util.h', 'src/core/lib/matchers/matchers.h', 'src/core/lib/profiling/timers.h', + 'src/core/lib/promise/activity.h', + 'src/core/lib/promise/context.h', + 'src/core/lib/promise/detail/basic_seq.h', + 'src/core/lib/promise/detail/promise_factory.h', + 'src/core/lib/promise/detail/promise_like.h', + 'src/core/lib/promise/detail/status.h', + 'src/core/lib/promise/detail/switch.h', + 'src/core/lib/promise/exec_ctx_wakeup_scheduler.h', + 'src/core/lib/promise/loop.h', + 'src/core/lib/promise/map.h', + 'src/core/lib/promise/poll.h', + 'src/core/lib/promise/race.h', + 'src/core/lib/promise/seq.h', + 'src/core/lib/resource_quota/api.h', + 'src/core/lib/resource_quota/memory_quota.h', + 'src/core/lib/resource_quota/resource_quota.h', + 'src/core/lib/resource_quota/thread_quota.h', + 'src/core/lib/resource_quota/trace.h', 'src/core/lib/security/authorization/authorization_engine.h', 'src/core/lib/security/authorization/authorization_policy_provider.h', 'src/core/lib/security/authorization/evaluate_args.h', @@ -2254,8 +2297,6 @@ Pod::Spec.new do |s| 'test/core/util/reconnect_server.h', 'test/core/util/resolve_localhost_ip46.cc', 'test/core/util/resolve_localhost_ip46.h', - 'test/core/util/resource_user_util.cc', - 'test/core/util/resource_user_util.h', 'test/core/util/slice_splitter.cc', 'test/core/util/slice_splitter.h', 'test/core/util/stack_tracer.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 16f7c53054a..43c4e6be18b 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -57,6 +57,7 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/event_engine/event_engine.h ) s.files += %w( include/grpc/event_engine/internal/memory_allocator_impl.h ) s.files += %w( include/grpc/event_engine/memory_allocator.h ) + s.files += %w( include/grpc/event_engine/memory_request.h ) s.files += %w( include/grpc/event_engine/port.h ) s.files += %w( include/grpc/fork.h ) s.files += %w( include/grpc/grpc.h ) @@ -791,6 +792,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/event_engine/event_engine.cc ) s.files += %w( src/core/lib/event_engine/event_engine_factory.cc ) s.files += %w( src/core/lib/event_engine/event_engine_factory.h ) + s.files += %w( src/core/lib/event_engine/memory_allocator.cc ) s.files += %w( src/core/lib/event_engine/sockaddr.cc ) s.files += %w( src/core/lib/event_engine/sockaddr.h ) s.files += %w( src/core/lib/gpr/alloc.cc ) @@ -840,6 +842,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/bitset.h ) s.files += %w( src/core/lib/gprpp/chunked_vector.h ) s.files += %w( src/core/lib/gprpp/construct_destruct.h ) + s.files += %w( src/core/lib/gprpp/cpp_impl_of.h ) s.files += %w( src/core/lib/gprpp/debug_location.h ) s.files += %w( src/core/lib/gprpp/dual_ref_counted.h ) s.files += %w( src/core/lib/gprpp/examine_stack.cc ) @@ -989,8 +992,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/resolve_address_custom.h ) s.files += %w( src/core/lib/iomgr/resolve_address_posix.cc ) s.files += %w( src/core/lib/iomgr/resolve_address_windows.cc ) - s.files += %w( src/core/lib/iomgr/resource_quota.cc ) - s.files += %w( src/core/lib/iomgr/resource_quota.h ) s.files += %w( src/core/lib/iomgr/sockaddr.h ) s.files += %w( src/core/lib/iomgr/sockaddr_posix.h ) s.files += %w( src/core/lib/iomgr/sockaddr_windows.h ) @@ -1062,6 +1063,30 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/profiling/basic_timers.cc ) s.files += %w( src/core/lib/profiling/stap_timers.cc ) s.files += %w( src/core/lib/profiling/timers.h ) + s.files += %w( src/core/lib/promise/activity.cc ) + s.files += %w( src/core/lib/promise/activity.h ) + s.files += %w( src/core/lib/promise/context.h ) + s.files += %w( src/core/lib/promise/detail/basic_seq.h ) + s.files += %w( src/core/lib/promise/detail/promise_factory.h ) + s.files += %w( src/core/lib/promise/detail/promise_like.h ) + s.files += %w( src/core/lib/promise/detail/status.h ) + s.files += %w( src/core/lib/promise/detail/switch.h ) + s.files += %w( src/core/lib/promise/exec_ctx_wakeup_scheduler.h ) + s.files += %w( src/core/lib/promise/loop.h ) + s.files += %w( src/core/lib/promise/map.h ) + s.files += %w( src/core/lib/promise/poll.h ) + s.files += %w( src/core/lib/promise/race.h ) + s.files += %w( src/core/lib/promise/seq.h ) + s.files += %w( src/core/lib/resource_quota/api.cc ) + s.files += %w( src/core/lib/resource_quota/api.h ) + s.files += %w( src/core/lib/resource_quota/memory_quota.cc ) + s.files += %w( src/core/lib/resource_quota/memory_quota.h ) + s.files += %w( src/core/lib/resource_quota/resource_quota.cc ) + s.files += %w( src/core/lib/resource_quota/resource_quota.h ) + s.files += %w( src/core/lib/resource_quota/thread_quota.cc ) + s.files += %w( src/core/lib/resource_quota/thread_quota.h ) + s.files += %w( src/core/lib/resource_quota/trace.cc ) + s.files += %w( src/core/lib/resource_quota/trace.h ) s.files += %w( src/core/lib/security/authorization/authorization_engine.h ) s.files += %w( src/core/lib/security/authorization/authorization_policy_provider.h ) s.files += %w( src/core/lib/security/authorization/authorization_policy_provider_vtable.cc ) diff --git a/grpc.gyp b/grpc.gyp index 7ccbcf4fbd4..a4194c1cc12 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -823,6 +823,7 @@ 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/event_engine.cc', 'src/core/lib/event_engine/event_engine_factory.cc', + 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/sockaddr.cc', 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', @@ -887,7 +888,6 @@ 'src/core/lib/iomgr/resolve_address_custom.cc', 'src/core/lib/iomgr/resolve_address_posix.cc', 'src/core/lib/iomgr/resolve_address_windows.cc', - 'src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/iomgr/socket_factory_posix.cc', 'src/core/lib/iomgr/socket_mutator.cc', 'src/core/lib/iomgr/socket_utils_common_posix.cc', @@ -927,6 +927,12 @@ 'src/core/lib/json/json_util.cc', 'src/core/lib/json/json_writer.cc', 'src/core/lib/matchers/matchers.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', 'src/core/lib/security/authorization/evaluate_args.cc', 'src/core/lib/security/authorization/sdk_server_authz_filter.cc', @@ -1091,7 +1097,6 @@ 'test/core/util/port_server_client.cc', 'test/core/util/reconnect_server.cc', 'test/core/util/resolve_localhost_ip46.cc', - 'test/core/util/resource_user_util.cc', 'test/core/util/slice_splitter.cc', 'test/core/util/stack_tracer.cc', 'test/core/util/subprocess_posix.cc', @@ -1125,7 +1130,6 @@ 'test/core/util/port_server_client.cc', 'test/core/util/reconnect_server.cc', 'test/core/util/resolve_localhost_ip46.cc', - 'test/core/util/resource_user_util.cc', 'test/core/util/slice_splitter.cc', 'test/core/util/stack_tracer.cc', 'test/core/util/subprocess_posix.cc', @@ -1282,6 +1286,7 @@ 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/event_engine.cc', 'src/core/lib/event_engine/event_engine_factory.cc', + 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/sockaddr.cc', 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', @@ -1345,7 +1350,6 @@ 'src/core/lib/iomgr/resolve_address_custom.cc', 'src/core/lib/iomgr/resolve_address_posix.cc', 'src/core/lib/iomgr/resolve_address_windows.cc', - 'src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/iomgr/socket_factory_posix.cc', 'src/core/lib/iomgr/socket_mutator.cc', 'src/core/lib/iomgr/socket_utils_common_posix.cc', @@ -1384,6 +1388,12 @@ 'src/core/lib/json/json_reader.cc', 'src/core/lib/json/json_util.cc', 'src/core/lib/json/json_writer.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', 'src/core/lib/security/authorization/authorization_policy_provider_null_vtable.cc', 'src/core/lib/slice/b64.cc', 'src/core/lib/slice/percent_encoding.cc', diff --git a/include/grpc/event_engine/internal/memory_allocator_impl.h b/include/grpc/event_engine/internal/memory_allocator_impl.h index a7900574160..e0ca2f5ea75 100644 --- a/include/grpc/event_engine/internal/memory_allocator_impl.h +++ b/include/grpc/event_engine/internal/memory_allocator_impl.h @@ -21,42 +21,12 @@ #include #include +#include #include -// forward-declaring an internal struct, not used publicly. -struct grpc_slice_buffer; - namespace grpc_event_engine { namespace experimental { -/// Reservation request - how much memory do we want to allocate? -class MemoryRequest { - public: - /// Request a fixed amount of memory. - // NOLINTNEXTLINE(google-explicit-constructor) - MemoryRequest(size_t n) : min_(n), max_(n) {} - /// Request a range of memory. - /// Requires: \a min <= \a max. - /// Requires: \a max <= max_size() - MemoryRequest(size_t min, size_t max) : min_(min), max_(max) {} - - /// Maximum allowable request size - hard coded to 1GB. - static constexpr size_t max_allowed_size() { return 1024 * 1024 * 1024; } - - /// Increase the size by \a amount. - /// Undefined behavior if min() + amount or max() + amount overflows. - MemoryRequest Increase(size_t amount) const { - return MemoryRequest(min_ + amount, max_ + amount); - } - - size_t min() const { return min_; } - size_t max() const { return max_; } - - private: - size_t min_; - size_t max_; -}; - namespace internal { /// Underlying memory allocation interface. diff --git a/include/grpc/event_engine/memory_allocator.h b/include/grpc/event_engine/memory_allocator.h index fb200da9603..8c812671311 100644 --- a/include/grpc/event_engine/memory_allocator.h +++ b/include/grpc/event_engine/memory_allocator.h @@ -16,6 +16,8 @@ #include +#include // for abort() + #include #include #include @@ -42,6 +44,9 @@ class SliceBuffer { grpc_slice_buffer* slice_buffer_; }; +// Tracks memory allocated by one system. +// Is effectively a thin wrapper/smart pointer for a MemoryAllocatorImpl, +// providing a convenient and stable API. class MemoryAllocator { public: /// Construct a MemoryAllocator given an internal::MemoryAllocatorImpl @@ -50,6 +55,8 @@ class MemoryAllocator { explicit MemoryAllocator( std::shared_ptr allocator) : allocator_(std::move(allocator)) {} + // Construct an invalid MemoryAllocator. + MemoryAllocator() : allocator_(nullptr) {} ~MemoryAllocator() { if (allocator_ != nullptr) allocator_->Shutdown(); } @@ -60,6 +67,14 @@ class MemoryAllocator { MemoryAllocator(MemoryAllocator&&) = default; MemoryAllocator& operator=(MemoryAllocator&&) = default; + /// Drop the underlying allocator and make this an empty object. + /// The object will not be usable after this call unless it's a valid + /// allocator is moved into it. + void Reset() { + if (allocator_ != nullptr) allocator_->Shutdown(); + allocator_.reset(); + } + /// Reserve bytes from the quota. /// If we enter overcommit, reclamation will begin concurrently. /// Returns the number of bytes reserved. @@ -68,13 +83,6 @@ class MemoryAllocator { /// Release some bytes that were previously reserved. void Release(size_t n) { return allocator_->Release(n); } - /// Return a pointer to the underlying implementation. - /// Note that the interface of said implementatoin is unstable and likely to - /// change at any time. - internal::MemoryAllocatorImpl* get_internal_impl_ptr() { - return allocator_.get(); - } - // // The remainder of this type are helper functions implemented in terms of // Reserve/Release. @@ -175,8 +183,15 @@ class MemoryAllocator { }; protected: - const std::shared_ptr& allocator() { - return allocator_; + /// Return a pointer to the underlying implementation. + /// Note that the interface of said implementation is unstable and likely to + /// change at any time. + internal::MemoryAllocatorImpl* get_internal_impl_ptr() { + return allocator_.get(); + } + + const internal::MemoryAllocatorImpl* get_internal_impl_ptr() const { + return allocator_.get(); } private: @@ -198,10 +213,11 @@ class MemoryAllocatorFactory { virtual ~MemoryAllocatorFactory() = default; /// On Endpoint creation, call \a CreateMemoryAllocator to create a new /// allocator for the endpoint. + /// \a name is used to label the memory allocator in debug logs. /// Typically we'll want to: - /// auto allocator = factory->CreateMemoryAllocator(); + /// auto allocator = factory->CreateMemoryAllocator(peer_address_string); /// auto* endpoint = allocator->New(std::move(allocator), ...); - virtual MemoryAllocator CreateMemoryAllocator() = 0; + virtual MemoryAllocator CreateMemoryAllocator(absl::string_view name) = 0; }; } // namespace experimental diff --git a/include/grpc/event_engine/memory_request.h b/include/grpc/event_engine/memory_request.h new file mode 100644 index 00000000000..fa15e26cbf6 --- /dev/null +++ b/include/grpc/event_engine/memory_request.h @@ -0,0 +1,57 @@ +// Copyright 2021 The 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_EVENT_ENGINE_MEMORY_REQUEST_H +#define GRPC_EVENT_ENGINE_MEMORY_REQUEST_H + +#include + +#include + +#include "absl/strings/string_view.h" + +namespace grpc_event_engine { +namespace experimental { + +/// Reservation request - how much memory do we want to allocate? +class MemoryRequest { + public: + /// Request a fixed amount of memory. + // NOLINTNEXTLINE(google-explicit-constructor) + MemoryRequest(size_t n) : min_(n), max_(n) {} + /// Request a range of memory. + /// Requires: \a min <= \a max. + /// Requires: \a max <= max_size() + MemoryRequest(size_t min, size_t max) : min_(min), max_(max) {} + + /// Maximum allowable request size - hard coded to 1GB. + static constexpr size_t max_allowed_size() { return 1024 * 1024 * 1024; } + + /// Increase the size by \a amount. + /// Undefined behavior if min() + amount or max() + amount overflows. + MemoryRequest Increase(size_t amount) const { + return MemoryRequest(min_ + amount, max_ + amount); + } + + size_t min() const { return min_; } + size_t max() const { return max_; } + + private: + size_t min_; + size_t max_; +}; + +} // namespace experimental +} // namespace grpc_event_engine + +#endif // GRPC_EVENT_ENGINE_MEMORY_REQUEST_H diff --git a/package.xml b/package.xml index a028b948425..31ab5a475eb 100644 --- a/package.xml +++ b/package.xml @@ -37,6 +37,7 @@ + @@ -771,6 +772,7 @@ + @@ -820,6 +822,7 @@ + @@ -969,8 +972,6 @@ - - @@ -1042,6 +1043,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc b/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc index a430e7a9d61..fa29ecea817 100644 --- a/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc @@ -127,9 +127,8 @@ GoogleCloud2ProdResolver::MetadataQuery::MetadataQuery( request.http.path = const_cast(path); request.http.hdr_count = 1; request.http.hdrs = &header; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("c2p_resolver"); - grpc_httpcli_get(&context_, pollent, resource_quota, &request, + // TODO(ctiller): share the quota from whomever instantiates this! + grpc_httpcli_get(&context_, pollent, ResourceQuota::Default(), &request, ExecCtx::Get()->Now() + 10000, // 10s timeout &on_done_, &response_); } diff --git a/src/core/ext/transport/binder/client/channel_create_impl.cc b/src/core/ext/transport/binder/client/channel_create_impl.cc index a3fb6a4227e..63449dbcb54 100644 --- a/src/core/ext/transport/binder/client/channel_create_impl.cc +++ b/src/core/ext/transport/binder/client/channel_create_impl.cc @@ -56,9 +56,10 @@ grpc_channel* CreateDirectBinderChannelImplForTesting( grpc_channel_args* final_args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); grpc_error_handle error = GRPC_ERROR_NONE; - grpc_channel* channel = grpc_channel_create( - "binder_target_placeholder", final_args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, &error); + grpc_channel* channel = + grpc_channel_create("binder_target_placeholder", final_args, + GRPC_CLIENT_DIRECT_CHANNEL, transport, &error); + // TODO(mingcl): Handle error properly GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_channel_args_destroy(final_args); return channel; @@ -80,7 +81,7 @@ grpc_channel* CreateClientBinderChannelImpl(const grpc_channel_args* args) { grpc_channel* channel = grpc_channel_create("binder_channel_target_placeholder", new_args, - GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, &error); + GRPC_CLIENT_CHANNEL, nullptr, &error); // Clean up. grpc_channel_args_destroy(new_args); diff --git a/src/core/ext/transport/binder/server/binder_server.cc b/src/core/ext/transport/binder/server/binder_server.cc index c4fd226f465..4d68e46edf5 100644 --- a/src/core/ext/transport/binder/server/binder_server.cc +++ b/src/core/ext/transport/binder/server/binder_server.cc @@ -214,8 +214,8 @@ class BinderServerListener : public Server::ListenerInterface { std::move(client_binder), security_policy_); GPR_ASSERT(server_transport); grpc_channel_args* args = grpc_channel_args_copy(server_->channel_args()); - grpc_error_handle error = server_->SetupTransport(server_transport, nullptr, - args, nullptr, nullptr); + grpc_error_handle error = + server_->SetupTransport(server_transport, nullptr, args, nullptr); grpc_channel_args_destroy(args); return grpc_error_to_absl_status(error); } diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 03e95a13c5c..d2c55ff1263 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -43,9 +43,6 @@ Chttp2Connector::Chttp2Connector() { } Chttp2Connector::~Chttp2Connector() { - if (resource_quota_ != nullptr) { - grpc_resource_quota_unref_internal(resource_quota_); - } if (endpoint_ != nullptr) { grpc_endpoint_destroy(endpoint_); } @@ -64,11 +61,6 @@ void Chttp2Connector::Connect(const Args& args, Result* result, connecting_ = true; GPR_ASSERT(endpoint_ == nullptr); ep = &endpoint_; - if (resource_quota_ != nullptr) { - grpc_resource_quota_unref_internal(resource_quota_); - } - resource_quota_ = - grpc_resource_quota_from_channel_args(args.channel_args, true); } // In some implementations, the closure can be flushed before // grpc_tcp_client_connect() returns, and since the closure requires access @@ -77,12 +69,8 @@ void Chttp2Connector::Connect(const Args& args, Result* result, // grpc_tcp_client_connect() will fill endpoint_ with proper contents, and we // make sure that we still exist at that point by taking a ref. Ref().release(); // Ref held by callback. - grpc_tcp_client_connect( - &connected_, ep, - grpc_slice_allocator_create(resource_quota_, - grpc_sockaddr_to_string(args.address, false), - args.channel_args), - args.interested_parties, args.channel_args, args.address, args.deadline); + grpc_tcp_client_connect(&connected_, ep, args.interested_parties, + args.channel_args, args.address, args.deadline); } void Chttp2Connector::Shutdown(grpc_error_handle error) { @@ -175,12 +163,8 @@ void Chttp2Connector::OnHandshakeDone(void* arg, grpc_error_handle error) { self->result_->Reset(); NullThenSchedClosure(DEBUG_LOCATION, &self->notify_, error); } else if (args->endpoint != nullptr) { - self->result_->transport = grpc_create_chttp2_transport( - args->args, args->endpoint, true, - grpc_resource_user_create( - self->resource_quota_, - absl::StrCat(grpc_endpoint_get_peer(args->endpoint), - ":connector_transport"))); + self->result_->transport = + grpc_create_chttp2_transport(args->args, args->endpoint, true); self->result_->socket_node = grpc_chttp2_transport_get_socket_node(self->result_->transport); self->result_->channel_args = args->args; diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h index 5ed8ab416a1..59db078f3b7 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.h +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h @@ -24,7 +24,6 @@ #include "src/core/ext/filters/client_channel/connector.h" #include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker_registry.h" -#include "src/core/lib/iomgr/resource_quota.h" namespace grpc_core { @@ -69,7 +68,6 @@ class Chttp2Connector : public SubchannelConnector { grpc_closure on_timeout_; absl::optional notify_error_; RefCountedPtr handshake_mgr_; - grpc_resource_quota* resource_quota_ = nullptr; }; } // namespace grpc_core diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index 8d5674ad9ea..b15f16d2fee 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -26,6 +26,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/transport/chttp2/client/chttp2_connector.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" @@ -57,10 +58,12 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args, grpc_arg arg = grpc_channel_arg_string_create( const_cast(GRPC_ARG_SERVER_URI), canonical_target.get()); const char* to_remove[] = {GRPC_ARG_SERVER_URI}; - grpc_channel_args* new_args = + grpc_channel_args* new_args0 = grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); + grpc_channel_args* new_args = EnsureResourceQuotaInChannelArgs(new_args0); + grpc_channel_args_destroy(new_args0); grpc_channel* channel = grpc_channel_create( - target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, error); + target, new_args, GRPC_CLIENT_CHANNEL, nullptr, error); grpc_channel_args_destroy(new_args); return channel; } diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc index db9d4d53f0b..ed3cf57dd9f 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc @@ -31,6 +31,7 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/tcp_client_posix.h" #include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/transport.h" @@ -44,26 +45,21 @@ grpc_channel* grpc_insecure_channel_create_from_fd( grpc_arg default_authority_arg = grpc_channel_arg_string_create( const_cast(GRPC_ARG_DEFAULT_AUTHORITY), const_cast("test.authority")); + args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); grpc_channel_args* final_args = - grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); + grpc_core::EnsureResourceQuotaInChannelArgs(args); + grpc_channel_args_destroy(args); int flags = fcntl(fd, F_GETFL, 0); GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); - grpc_resource_quota* resource_quota = - grpc_resource_quota_from_channel_args(args, true); - grpc_slice_allocator* allocator = grpc_slice_allocator_create( - resource_quota, "fd-client:endpoint", final_args); grpc_endpoint* client = grpc_tcp_client_create_from_fd( - grpc_fd_create(fd, "client", true), args, "fd-client", allocator); - grpc_transport* transport = grpc_create_chttp2_transport( - final_args, client, true, - grpc_resource_user_create(resource_quota, "fd-client:transport")); - grpc_resource_quota_unref_internal(resource_quota); + grpc_fd_create(fd, "client", true), final_args, "fd-client"); + grpc_transport* transport = + grpc_create_chttp2_transport(final_args, client, true); GPR_ASSERT(transport); grpc_error_handle error = GRPC_ERROR_NONE; - grpc_channel* channel = - grpc_channel_create(target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, &error); + grpc_channel* channel = grpc_channel_create( + target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error); grpc_channel_args_destroy(final_args); if (channel != nullptr) { grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index 68cd3a916ca..8287bf389e1 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -28,6 +28,7 @@ #include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/lib/slice/slice_internal.h" @@ -120,7 +121,7 @@ grpc_channel* CreateChannel(const char* target, const grpc_channel_args* args, grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1); grpc_channel* channel = grpc_channel_create( - target, new_args, GRPC_CLIENT_CHANNEL, nullptr, nullptr, 0, error); + target, new_args, GRPC_CLIENT_CHANNEL, nullptr, error); grpc_channel_args_destroy(new_args); return channel; } @@ -166,8 +167,11 @@ grpc_channel* grpc_secure_channel_create(grpc_channel_credentials* creds, grpc_arg args_to_add[] = {channel_factory_arg, grpc_channel_credentials_to_arg(creds)}; const char* arg_to_remove = channel_factory_arg.key; - grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove( + grpc_channel_args* updated_args = grpc_channel_args_copy_and_add_and_remove( args, &arg_to_remove, 1, args_to_add, GPR_ARRAY_SIZE(args_to_add)); + grpc_channel_args* new_args = + grpc_core::EnsureResourceQuotaInChannelArgs(updated_args); + grpc_channel_args_destroy(updated_args); new_args = creds->update_arguments(new_args); // Create channel. channel = grpc_core::CreateChannel(target, new_args, &error); diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 09fcc2bab2a..40ba48a7595 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -48,9 +48,10 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/resource_quota/api.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" @@ -75,8 +76,7 @@ class Chttp2ServerListener : public Server::ListenerInterface { // Do not instantiate directly. Use one of the factory methods above. Chttp2ServerListener(Server* server, grpc_channel_args* args, - Chttp2ServerArgsModifier args_modifier, - grpc_resource_quota* resource_quota); + Chttp2ServerArgsModifier args_modifier); ~Chttp2ServerListener() override; void Start(Server* server, @@ -114,8 +114,7 @@ class Chttp2ServerListener : public Server::ListenerInterface { HandshakingState(RefCountedPtr connection_ref, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor, - grpc_channel_args* args, - grpc_resource_user* channel_resource_user); + grpc_channel_args* args); ~HandshakingState() override; @@ -141,13 +140,11 @@ class Chttp2ServerListener : public Server::ListenerInterface { grpc_closure on_timeout_ ABSL_GUARDED_BY(&connection_->mu_); grpc_closure on_receive_settings_ ABSL_GUARDED_BY(&connection_->mu_); grpc_pollset_set* const interested_parties_; - grpc_resource_user* channel_resource_user_; }; ActiveConnection(grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor, - grpc_channel_args* args, - grpc_resource_user* channel_resource_user); + grpc_channel_args* args, MemoryOwner memory_owner); ~ActiveConnection() override; void Orphan() override; @@ -241,7 +238,7 @@ class Chttp2ServerListener : public Server::ListenerInterface { grpc_closure tcp_server_shutdown_complete_ ABSL_GUARDED_BY(mu_); grpc_closure* on_destroy_done_ ABSL_GUARDED_BY(mu_) = nullptr; RefCountedPtr channelz_listen_socket_; - grpc_resource_quota* resource_quota_; + MemoryQuotaRefPtr memory_quota_; }; // @@ -313,14 +310,13 @@ grpc_millis GetConnectionDeadline(const grpc_channel_args* args) { Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState( RefCountedPtr connection_ref, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor, - grpc_channel_args* args, grpc_resource_user* channel_resource_user) + grpc_channel_args* args) : connection_(std::move(connection_ref)), accepting_pollset_(accepting_pollset), acceptor_(acceptor), handshake_mgr_(MakeRefCounted()), deadline_(GetConnectionDeadline(args)), - interested_parties_(grpc_pollset_set_create()), - channel_resource_user_(channel_resource_user) { + interested_parties_(grpc_pollset_set_create()) { grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_); CoreConfiguration::Get().handshaker_registry().AddHandshakers( HANDSHAKER_SERVER, args, interested_parties_, handshake_mgr_.get()); @@ -329,9 +325,6 @@ Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState( Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() { grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_); grpc_pollset_set_destroy(interested_parties_); - if (channel_resource_user_ != nullptr) { - grpc_resource_user_unref(channel_resource_user_); - } gpr_free(acceptor_); } @@ -416,18 +409,12 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone( // handshaker may have handed off the connection to some external // code, so we can just clean up here without creating a transport. if (args->endpoint != nullptr) { - grpc_transport* transport = grpc_create_chttp2_transport( - args->args, args->endpoint, false, - grpc_resource_user_create( - self->connection_->listener_->resource_quota_, - absl::StrCat(grpc_endpoint_get_peer(args->endpoint), - ":chttp2_server_transport"))); + grpc_transport* transport = + grpc_create_chttp2_transport(args->args, args->endpoint, false); grpc_error_handle channel_init_err = self->connection_->listener_->server_->SetupTransport( transport, self->accepting_pollset_, args->args, - grpc_chttp2_transport_get_socket_node(transport), - self->channel_resource_user_, GRPC_RESOURCE_QUOTA_CHANNEL_SIZE); - self->channel_resource_user_ = nullptr; + grpc_chttp2_transport_get_socket_node(transport)); if (channel_init_err == GRPC_ERROR_NONE) { // Use notify_on_receive_settings callback to enforce the // handshake deadline. @@ -491,10 +478,6 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone( gpr_free(self->acceptor_); self->acceptor_ = nullptr; OrphanablePtr connection; - if (self->channel_resource_user_ != nullptr) { - grpc_resource_user_free(self->channel_resource_user_, - GRPC_RESOURCE_QUOTA_CHANNEL_SIZE); - } if (cleanup_connection) { MutexLock listener_lock(&self->connection_->listener_->mu_); auto it = self->connection_->listener_->connections_.find( @@ -513,9 +496,9 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone( Chttp2ServerListener::ActiveConnection::ActiveConnection( grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor, - grpc_channel_args* args, grpc_resource_user* channel_resource_user) - : handshaking_state_(MakeOrphanable( - Ref(), accepting_pollset, acceptor, args, channel_resource_user)) { + grpc_channel_args* args, MemoryOwner memory_owner) + : handshaking_state_(memory_owner.MakeOrphanable( + Ref(), accepting_pollset, acceptor, args)) { GRPC_CLOSURE_INIT(&on_close_, ActiveConnection::OnClose, this, grpc_schedule_on_exec_ctx); } @@ -600,14 +583,9 @@ grpc_error_handle Chttp2ServerListener::Create( grpc_error_handle error = [&]() { grpc_error_handle error = GRPC_ERROR_NONE; // Create Chttp2ServerListener. - listener = new Chttp2ServerListener( - server, args, args_modifier, - grpc_resource_quota_from_channel_args(args, true)); - grpc_resource_quota_ref_internal(listener->resource_quota_); - error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, args, - grpc_slice_allocator_factory_create(listener->resource_quota_), - &listener->tcp_server_); + listener = new Chttp2ServerListener(server, args, args_modifier); + error = grpc_tcp_server_create(&listener->tcp_server_shutdown_complete_, + args, &listener->tcp_server_); if (error != GRPC_ERROR_NONE) return error; if (server->config_fetcher() != nullptr) { listener->resolved_address_ = *addr; @@ -648,14 +626,10 @@ grpc_error_handle Chttp2ServerListener::Create( grpc_error_handle Chttp2ServerListener::CreateWithAcceptor( Server* server, const char* name, grpc_channel_args* args, Chttp2ServerArgsModifier args_modifier) { - Chttp2ServerListener* listener = new Chttp2ServerListener( - server, args, args_modifier, - grpc_resource_quota_from_channel_args(args, true)); - grpc_resource_quota_ref_internal(listener->resource_quota_); + Chttp2ServerListener* listener = + new Chttp2ServerListener(server, args, args_modifier); grpc_error_handle error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, args, - grpc_slice_allocator_factory_create(listener->resource_quota_), - &listener->tcp_server_); + &listener->tcp_server_shutdown_complete_, args, &listener->tcp_server_); if (error != GRPC_ERROR_NONE) { delete listener; return error; @@ -670,11 +644,11 @@ grpc_error_handle Chttp2ServerListener::CreateWithAcceptor( Chttp2ServerListener::Chttp2ServerListener( Server* server, grpc_channel_args* args, - Chttp2ServerArgsModifier args_modifier, grpc_resource_quota* resource_quota) + Chttp2ServerArgsModifier args_modifier) : server_(server), args_modifier_(args_modifier), args_(args), - resource_quota_(resource_quota) { + memory_quota_(ResourceQuotaFromChannelArgs(args)->memory_quota()) { GRPC_CLOSURE_INIT(&tcp_server_shutdown_complete_, TcpServerShutdownComplete, this, grpc_schedule_on_exec_ctx); } @@ -687,7 +661,6 @@ Chttp2ServerListener::~Chttp2ServerListener() { ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, GRPC_ERROR_NONE); ExecCtx::Get()->Flush(); } - grpc_resource_quota_unref_internal(resource_quota_); grpc_channel_args_destroy(args_); } @@ -766,11 +739,10 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, } args_to_destroy = args; } - grpc_resource_user* channel_resource_user = grpc_resource_user_create( - self->resource_quota_, + auto memory_owner = self->memory_quota_->CreateMemoryOwner( absl::StrCat(grpc_endpoint_get_peer(tcp), ":server_channel")); - auto connection = MakeOrphanable( - accepting_pollset, acceptor, args, channel_resource_user); + auto connection = memory_owner.MakeOrphanable( + accepting_pollset, acceptor, args, std::move(memory_owner)); // We no longer own acceptor acceptor = nullptr; // Hold a ref to connection to allow starting handshake outside the @@ -781,20 +753,13 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, MutexLock lock(&self->mu_); // Shutdown the the connection if listener's stopped serving. if (!self->shutdown_ && self->is_serving_) { - if (!grpc_resource_user_safe_alloc(channel_resource_user, - GRPC_RESOURCE_QUOTA_CHANNEL_SIZE)) { - gpr_log( - GPR_INFO, - "Memory quota exhausted, rejecting connection, no handshaking."); - } else { - // This ref needs to be taken in the critical region after having made - // sure that the listener has not been Orphaned, so as to avoid - // heap-use-after-free issues where `Ref()` is invoked when the ref of - // tcp_server_ has already reached 0. (Ref() implementation of - // Chttp2ServerListener is grpc_tcp_server_ref().) - listener_ref = self->Ref(); - self->connections_.emplace(connection.get(), std::move(connection)); - } + // This ref needs to be taken in the critical region after having made + // sure that the listener has not been Orphaned, so as to avoid + // heap-use-after-free issues where `Ref()` is invoked when the ref of + // tcp_server_ has already reached 0. (Ref() implementation of + // Chttp2ServerListener is grpc_tcp_server_ref().) + listener_ref = self->Ref(); + self->connections_.emplace(connection.get(), std::move(connection)); } } if (connection != nullptr) { diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc index cdc79f28f0d..78eff9756c8 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc @@ -33,6 +33,7 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" @@ -45,20 +46,15 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, const grpc_channel_args* server_args = core_server->channel_args(); std::string name = absl::StrCat("fd:", fd); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create(name.c_str()); + auto memory_quota = + grpc_core::ResourceQuotaFromChannelArgs(server_args)->memory_quota(); grpc_endpoint* server_endpoint = grpc_tcp_create( - grpc_fd_create(fd, name.c_str(), true), server_args, name, - grpc_slice_allocator_create(resource_quota, name, server_args)); + grpc_fd_create(fd, name.c_str(), true), server_args, name); grpc_transport* transport = grpc_create_chttp2_transport( - server_args, server_endpoint, false /* is_client */, - grpc_resource_user_create(resource_quota, - absl::StrCat(name, ":transport"))); - grpc_error_handle error = core_server->SetupTransport( - transport, nullptr, server_args, nullptr, - grpc_resource_user_create(resource_quota, - absl::StrCat(name, ":channel"))); - grpc_resource_quota_unref_internal(resource_quota); + server_args, server_endpoint, false /* is_client */ + ); + grpc_error_handle error = + core_server->SetupTransport(transport, nullptr, server_args, nullptr); if (error == GRPC_ERROR_NONE) { for (grpc_pollset* pollset : core_server->pollsets()) { grpc_endpoint_add_to_pollset(server_endpoint, pollset); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index adada2825d4..3a9b14c554b 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -46,6 +46,8 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/resource_quota/api.h" +#include "src/core/lib/resource_quota/trace.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/error_utils.h" @@ -126,8 +128,6 @@ static void connectivity_state_set(grpc_chttp2_transport* t, const absl::Status& status, const char* reason); -static void benign_reclaimer(void* arg, grpc_error_handle error); -static void destructive_reclaimer(void* arg, grpc_error_handle error); static void benign_reclaimer_locked(void* arg, grpc_error_handle error); static void destructive_reclaimer_locked(void* arg, grpc_error_handle error); @@ -442,14 +442,18 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) { } grpc_chttp2_transport::grpc_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, - grpc_resource_user* resource_user) + const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) : refs(1, GRPC_TRACE_FLAG_ENABLED(grpc_trace_chttp2_refcount) ? "chttp2_refcount" : nullptr), ep(ep), peer_string(grpc_endpoint_get_peer(ep)), - resource_user(resource_user), + memory_owner(grpc_core::ResourceQuotaFromChannelArgs(channel_args) + ->memory_quota() + ->CreateMemoryOwner(absl::StrCat( + grpc_endpoint_get_peer(ep), ":client_transport"))), + self_reservation( + memory_owner.MakeReservation(sizeof(grpc_chttp2_transport))), combiner(grpc_combiner_create()), state_tracker(is_client ? "client_transport" : "server_transport", GRPC_CHANNEL_READY), @@ -535,12 +539,11 @@ grpc_chttp2_transport::grpc_chttp2_transport( static void destroy_transport_locked(void* tp, grpc_error_handle /*error*/) { grpc_chttp2_transport* t = static_cast(tp); t->destroying = 1; - grpc_resource_user_shutdown(t->resource_user); - grpc_resource_user_unref(t->resource_user); close_transport_locked( t, grpc_error_set_int( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Transport destroyed"), GRPC_ERROR_INT_OCCURRED_DURING_WRITE, t->write_state)); + t->memory_owner.Reset(); // Must be the last line. GRPC_CHTTP2_UNREF_TRANSPORT(t, "destroy"); } @@ -646,6 +649,10 @@ grpc_chttp2_stream::grpc_chttp2_stream(grpc_chttp2_transport* t, : t(t), refcount(refcount), reffer(this), + stream_reservation(t->memory_owner.MakeReservation( + grpc_core::kResourceQuotaCallSize)), // TODO(ctiller): sizeof(*this), + // or better, move allocation to + // memory quota. initial_metadata_buffer(arena), trailing_metadata_buffer(arena) { if (server_data) { @@ -712,9 +719,6 @@ grpc_chttp2_stream::~grpc_chttp2_stream() { GRPC_ERROR_UNREF(write_closed_error); GRPC_ERROR_UNREF(byte_stream_error); flow_control.Destroy(); - if (!t->is_client) { - grpc_resource_user_free(t->resource_user, GRPC_RESOURCE_QUOTA_CALL_SIZE); - } GRPC_CHTTP2_UNREF_TRANSPORT(t, "stream"); grpc_core::ExecCtx::Run(DEBUG_LOCATION, destroy_stream_arg, GRPC_ERROR_NONE); } @@ -763,18 +767,6 @@ grpc_chttp2_stream* grpc_chttp2_parsing_accept_stream(grpc_chttp2_transport* t, if (t->accept_stream_cb == nullptr) { return nullptr; } - // Don't accept the stream if memory quota doesn't allow. Note that we should - // simply refuse the stream here instead of canceling the stream after it's - // accepted since the latter will create the call which costs much memory. - GPR_ASSERT(t->resource_user != nullptr); - if (!grpc_resource_user_safe_alloc(t->resource_user, - GRPC_RESOURCE_QUOTA_CALL_SIZE)) { - gpr_log(GPR_INFO, "Memory exhausted, rejecting the stream."); - grpc_chttp2_add_rst_stream_to_next_write(t, id, GRPC_HTTP2_REFUSED_STREAM, - nullptr); - grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_RST_STREAM); - return nullptr; - } grpc_chttp2_stream* accepting = nullptr; GPR_ASSERT(t->accepting_stream == nullptr); t->accepting_stream = &accepting; @@ -3156,10 +3148,19 @@ static void post_benign_reclaimer(grpc_chttp2_transport* t) { if (!t->benign_reclaimer_registered) { t->benign_reclaimer_registered = true; GRPC_CHTTP2_REF_TRANSPORT(t, "benign_reclaimer"); - GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, benign_reclaimer, t, - grpc_schedule_on_exec_ctx); - grpc_resource_user_post_reclaimer(t->resource_user, false, - &t->benign_reclaimer_locked); + t->memory_owner.PostReclaimer( + grpc_core::ReclamationPass::kBenign, + [t](absl::optional sweep) { + if (sweep.has_value()) { + GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, + benign_reclaimer_locked, t, + grpc_schedule_on_exec_ctx); + t->active_reclamation = std::move(*sweep); + t->combiner->Run(&t->benign_reclaimer_locked, GRPC_ERROR_NONE); + } else { + GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer"); + } + }); } } @@ -3167,20 +3168,22 @@ static void post_destructive_reclaimer(grpc_chttp2_transport* t) { if (!t->destructive_reclaimer_registered) { t->destructive_reclaimer_registered = true; GRPC_CHTTP2_REF_TRANSPORT(t, "destructive_reclaimer"); - GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked, destructive_reclaimer, - t, grpc_schedule_on_exec_ctx); - grpc_resource_user_post_reclaimer(t->resource_user, true, - &t->destructive_reclaimer_locked); + t->memory_owner.PostReclaimer( + grpc_core::ReclamationPass::kDestructive, + [t](absl::optional sweep) { + if (sweep.has_value()) { + GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked, + destructive_reclaimer_locked, t, + grpc_schedule_on_exec_ctx); + t->active_reclamation = std::move(*sweep); + t->combiner->Run(&t->destructive_reclaimer_locked, GRPC_ERROR_NONE); + } else { + GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer"); + } + }); } } -static void benign_reclaimer(void* arg, grpc_error_handle error) { - grpc_chttp2_transport* t = static_cast(arg); - t->combiner->Run(GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, - benign_reclaimer_locked, t, nullptr), - GRPC_ERROR_REF(error)); -} - static void benign_reclaimer_locked(void* arg, grpc_error_handle error) { grpc_chttp2_transport* t = static_cast(arg); if (error == GRPC_ERROR_NONE && @@ -3205,18 +3208,11 @@ static void benign_reclaimer_locked(void* arg, grpc_error_handle error) { } t->benign_reclaimer_registered = false; if (error != GRPC_ERROR_CANCELLED) { - grpc_resource_user_finish_reclamation(t->resource_user); + t->active_reclamation.Finish(); } GRPC_CHTTP2_UNREF_TRANSPORT(t, "benign_reclaimer"); } -static void destructive_reclaimer(void* arg, grpc_error_handle error) { - grpc_chttp2_transport* t = static_cast(arg); - t->combiner->Run(GRPC_CLOSURE_INIT(&t->destructive_reclaimer_locked, - destructive_reclaimer_locked, t, nullptr), - GRPC_ERROR_REF(error)); -} - static void destructive_reclaimer_locked(void* arg, grpc_error_handle error) { grpc_chttp2_transport* t = static_cast(arg); size_t n = grpc_chttp2_stream_map_size(&t->stream_map); @@ -3242,7 +3238,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error_handle error) { } } if (error != GRPC_ERROR_CANCELLED) { - grpc_resource_user_finish_reclamation(t->resource_user); + t->active_reclamation.Finish(); } GRPC_CHTTP2_UNREF_TRANSPORT(t, "destructive_reclaimer"); } @@ -3325,10 +3321,8 @@ grpc_chttp2_transport_get_socket_node(grpc_transport* transport) { } grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, - grpc_resource_user* resource_user) { - auto t = - new grpc_chttp2_transport(channel_args, ep, is_client, resource_user); + const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) { + auto t = new grpc_chttp2_transport(channel_args, ep, is_client); return &t->base; } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index f68a55df52c..3204a5f89ac 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -38,8 +38,7 @@ extern bool g_flow_control_enabled; /// from the caller; if the caller still needs the resource_user after creating /// a transport, the caller must take another ref. grpc_transport* grpc_create_chttp2_transport( - const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client, - grpc_resource_user* resource_user); + const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client); grpc_core::RefCountedPtr grpc_chttp2_transport_get_socket_node(grpc_transport* transport); diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index 739d15df6e7..19379034d0a 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -324,10 +324,8 @@ void StreamFlowControl::IncomingByteStreamUpdate(size_t max_size_hint, } // Take in a target and modifies it based on the memory pressure of the system -static double AdjustForMemoryPressure(grpc_resource_quota* quota, - double target) { +static double AdjustForMemoryPressure(double memory_pressure, double target) { // do not increase window under heavy memory pressure. - double memory_pressure = grpc_resource_quota_get_memory_pressure(quota); static const double kLowMemPressure = 0.1; static const double kZeroTarget = 22; static const double kHighMemPressure = 0.8; @@ -343,7 +341,9 @@ static double AdjustForMemoryPressure(grpc_resource_quota* quota, } double TransportFlowControl::TargetLogBdp() { - return AdjustForMemoryPressure(grpc_resource_user_quota(t_->resource_user), + return AdjustForMemoryPressure(t_->memory_owner.is_valid() + ? t_->memory_owner.InstantaneousPressure() + : 0.0, 1 + log2(bdp_estimator_.EstimateBdp())); } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 4e2c0e5fd1b..2f68464a7ac 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -41,6 +41,7 @@ #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata_batch.h" #include "src/core/lib/transport/transport_impl.h" @@ -287,8 +288,7 @@ typedef enum { struct grpc_chttp2_transport { grpc_chttp2_transport(const grpc_channel_args* channel_args, - grpc_endpoint* ep, bool is_client, - grpc_resource_user* resource_user); + grpc_endpoint* ep, bool is_client); ~grpc_chttp2_transport(); grpc_transport base; /* must be first */ @@ -296,7 +296,9 @@ struct grpc_chttp2_transport { grpc_endpoint* ep; std::string peer_string; - grpc_resource_user* resource_user; + grpc_core::MemoryOwner memory_owner; + const grpc_core::MemoryAllocator::Reservation self_reservation; + grpc_core::ReclamationSweep active_reclamation; grpc_core::Combiner* combiner; @@ -521,6 +523,8 @@ struct grpc_chttp2_stream { explicit Reffer(grpc_chttp2_stream* s); } reffer; + grpc_core::MemoryAllocator::Reservation stream_reservation; + grpc_closure destroy_stream; grpc_closure* destroy_stream_arg; diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc index ef1a9b577b7..3207eda8c1d 100644 --- a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc +++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc @@ -27,6 +27,7 @@ #include #include "src/core/ext/transport/cronet/transport/cronet_transport.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/transport_impl.h" @@ -52,6 +53,7 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( const_cast(GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER); disable_client_authority_filter_arg.type = GRPC_ARG_INTEGER; disable_client_authority_filter_arg.value.integer = 1; + args = grpc_core::EnsureResourceQuotaInChannelArgs(args); grpc_channel_args* new_args = grpc_channel_args_copy_and_add( args, &disable_client_authority_filter_arg, 1); @@ -60,7 +62,8 @@ GRPCAPI grpc_channel* grpc_cronet_secure_channel_create( grpc_core::ExecCtx exec_ctx; grpc_channel* channel = grpc_channel_create( - target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct, nullptr, 0, nullptr); + target, new_args, GRPC_CLIENT_DIRECT_CHANNEL, ct, nullptr); grpc_channel_args_destroy(new_args); + grpc_channel_args_destroy(args); return channel; } diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 31d5e0b73ce..9994987770c 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -29,6 +29,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/channel.h" @@ -1294,9 +1295,10 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, default_authority_arg.type = GRPC_ARG_STRING; default_authority_arg.key = const_cast(GRPC_ARG_DEFAULT_AUTHORITY); default_authority_arg.value.string = const_cast("inproc.authority"); + args = grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); grpc_channel_args* client_args = - grpc_channel_args_copy_and_add(args, &default_authority_arg, 1); - + grpc_core::EnsureResourceQuotaInChannelArgs(args); + grpc_channel_args_destroy(args); grpc_transport* server_transport; grpc_transport* client_transport; inproc_transports_create(&server_transport, server_args, &client_transport, @@ -1309,7 +1311,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server, if (error == GRPC_ERROR_NONE) { channel = grpc_channel_create("inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, - client_transport, nullptr, 0, &error); + client_transport, &error); if (error != GRPC_ERROR_NONE) { GPR_ASSERT(!channel); gpr_log(GPR_ERROR, "Failed to create client channel: %s", diff --git a/src/core/lib/channel/channel_stack_builder.cc b/src/core/lib/channel/channel_stack_builder.cc index 186cad3f0e6..b9c0e4c7f91 100644 --- a/src/core/lib/channel/channel_stack_builder.cc +++ b/src/core/lib/channel/channel_stack_builder.cc @@ -42,8 +42,6 @@ struct grpc_channel_stack_builder { // various set/get-able parameters grpc_channel_args* args; grpc_transport* transport; - grpc_resource_user* resource_user; - size_t preallocated_bytes; char* target; const char* name; }; diff --git a/src/core/lib/gpr/tls.h b/src/core/lib/gpr/tls.h index 5c9b69e6efe..9c2349e597d 100644 --- a/src/core/lib/gpr/tls.h +++ b/src/core/lib/gpr/tls.h @@ -118,6 +118,12 @@ class PthreadTlsImpl : TlsTypeConstrainer { return t; } + T operator->() const { + static_assert(std::is_pointer::value, + "operator-> only usable on pointers"); + return this->operator T(); + } + T operator=(T t) { char* src = reinterpret_cast(&t); for (pthread_key_t key : keys_) { diff --git a/src/core/lib/gprpp/cpp_impl_of.h b/src/core/lib/gprpp/cpp_impl_of.h new file mode 100644 index 00000000000..8d61dc8adf6 --- /dev/null +++ b/src/core/lib/gprpp/cpp_impl_of.h @@ -0,0 +1,45 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H +#define GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H + +namespace grpc_core { + +// Declares CppType to be the backing implementation of CType. +// Use via the curiously recursive template: +// class Foo : public CppImplOf {}; +// Provides casting methods each way. +// grpc_foo should be `typedef struct grpc_foo grpc_foo` and otherwise +// not defined. +template +class CppImplOf { + public: + // Convert the C struct to C++ + static CppType* FromC(CType* c_type) { + return reinterpret_cast(c_type); + } + + // Retrieve a c pointer (of the same ownership as this) + CType* c_ptr() { + return reinterpret_cast(static_cast(this)); + } + + protected: + ~CppImplOf() = default; +}; + +} // namespace grpc_core + +#endif // GRPC_CORE_LIB_GPRPP_CPP_IMPL_OF_H diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index ab4431e3153..1efdc372ed1 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -32,6 +32,7 @@ #include #include "src/core/lib/address_utils/sockaddr_utils.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/http/format_request.h" @@ -40,6 +41,7 @@ #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" namespace grpc_core { @@ -49,13 +51,13 @@ class InternalRequest { public: InternalRequest(const grpc_slice& request_text, grpc_httpcli_response* response, - grpc_resource_quota* resource_quota, absl::string_view host, + ResourceQuotaRefPtr resource_quota, absl::string_view host, absl::string_view ssl_host_override, grpc_millis deadline, const grpc_httpcli_handshaker* handshaker, grpc_closure* on_done, grpc_httpcli_context* context, grpc_polling_entity* pollent, const char* name) : request_text_(request_text), - resource_quota_(resource_quota), + resource_quota_(std::move(resource_quota)), host_(host), ssl_host_override_(ssl_host_override), deadline_(deadline), @@ -91,7 +93,6 @@ class InternalRequest { grpc_slice_buffer_destroy_internal(&incoming_); grpc_slice_buffer_destroy_internal(&outgoing_); GRPC_ERROR_UNREF(overall_error_); - grpc_resource_quota_unref_internal(resource_quota_); } private: @@ -203,10 +204,10 @@ class InternalRequest { addr = &addresses_->addrs[next_address_++]; GRPC_CLOSURE_INIT(&connected_, OnConnected, this, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect(&connected_, &ep_, - grpc_slice_allocator_create( - resource_quota_, grpc_sockaddr_to_uri(addr)), - context_->pollset_set, nullptr, addr, deadline_); + grpc_channel_args* args = ChannelArgsWrappingResourceQuota(resource_quota_); + grpc_tcp_client_connect(&connected_, &ep_, context_->pollset_set, args, + addr, deadline_); + grpc_channel_args_destroy(args); } static void OnResolved(void* arg, grpc_error_handle error) { @@ -224,7 +225,7 @@ class InternalRequest { grpc_resolved_addresses* addresses_ = nullptr; size_t next_address_ = 0; grpc_endpoint* ep_ = nullptr; - grpc_resource_quota* resource_quota_; + ResourceQuotaRefPtr resource_quota_; std::string host_; std::string ssl_host_override_; grpc_millis deadline_; @@ -266,16 +267,14 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context* context) { grpc_pollset_set_destroy(context->pollset_set); } -static void internal_request_begin(grpc_httpcli_context* context, - grpc_polling_entity* pollent, - grpc_resource_quota* resource_quota, - const grpc_httpcli_request* request, - grpc_millis deadline, grpc_closure* on_done, - grpc_httpcli_response* response, - const char* name, - const grpc_slice& request_text) { +static void internal_request_begin( + grpc_httpcli_context* context, grpc_polling_entity* pollent, + grpc_core::ResourceQuotaRefPtr resource_quota, + const grpc_httpcli_request* request, grpc_millis deadline, + grpc_closure* on_done, grpc_httpcli_response* response, const char* name, + const grpc_slice& request_text) { new grpc_core::InternalRequest( - request_text, response, resource_quota, request->host, + request_text, response, std::move(resource_quota), request->host, request->ssl_host_override, deadline, request->handshaker ? request->handshaker : &grpc_httpcli_plaintext, on_done, context, pollent, name); @@ -283,37 +282,35 @@ static void internal_request_begin(grpc_httpcli_context* context, void grpc_httpcli_get(grpc_httpcli_context* context, grpc_polling_entity* pollent, - grpc_resource_quota* resource_quota, + grpc_core::ResourceQuotaRefPtr resource_quota, const grpc_httpcli_request* request, grpc_millis deadline, grpc_closure* on_done, grpc_httpcli_response* response) { if (g_get_override && g_get_override(request, deadline, on_done, response)) { - grpc_resource_quota_unref_internal(resource_quota); return; } std::string name = absl::StrFormat("HTTP:GET:%s:%s", request->host, request->http.path); - internal_request_begin(context, pollent, resource_quota, request, deadline, - on_done, response, name.c_str(), + internal_request_begin(context, pollent, std::move(resource_quota), request, + deadline, on_done, response, name.c_str(), grpc_httpcli_format_get_request(request)); } void grpc_httpcli_post(grpc_httpcli_context* context, grpc_polling_entity* pollent, - grpc_resource_quota* resource_quota, + grpc_core::ResourceQuotaRefPtr resource_quota, const grpc_httpcli_request* request, const char* body_bytes, size_t body_size, grpc_millis deadline, grpc_closure* on_done, grpc_httpcli_response* response) { if (g_post_override && g_post_override(request, body_bytes, body_size, deadline, on_done, response)) { - grpc_resource_quota_unref_internal(resource_quota); return; } std::string name = absl::StrFormat("HTTP:POST:%s:%s", request->host, request->http.path); internal_request_begin( - context, pollent, resource_quota, request, deadline, on_done, response, - name.c_str(), + context, pollent, std::move(resource_quota), request, deadline, on_done, + response, name.c_str(), grpc_httpcli_format_post_request(request, body_bytes, body_size)); } diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h index 495feb3a62d..6c257900f12 100644 --- a/src/core/lib/http/httpcli.h +++ b/src/core/lib/http/httpcli.h @@ -30,7 +30,7 @@ #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/iomgr/pollset_set.h" -#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/resource_quota/resource_quota.h" /* User agent this library reports */ #define GRPC_HTTPCLI_USER_AGENT "grpc-httpcli/0.0" @@ -73,26 +73,28 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context* context); /* Asynchronously perform a HTTP GET. 'context' specifies the http context under which to do the get - 'pollset' indicates a grpc_pollset that is interested in the result - of the get - work on this pollset may be used to progress the get + 'pollent' indicates a grpc_polling_entity that is interested in the result + of the get - work on this entity may be used to progress the get operation - 'resource_quota: this function takes ownership of a ref from the caller - 'request' contains request parameters - these are caller owned and can be - destroyed once the call returns - 'deadline' contains a deadline for the request (or gpr_inf_future) + 'resource_quota' allows the caller to specify the quota against which to + allocate + 'request' contains request parameters - these are caller owned and + can be destroyed once the call returns 'deadline' contains a deadline for the + request (or gpr_inf_future) 'on_response' is a callback to report results to */ void grpc_httpcli_get(grpc_httpcli_context* context, grpc_polling_entity* pollent, - grpc_resource_quota* resource_quota, + grpc_core::ResourceQuotaRefPtr resource_quota, const grpc_httpcli_request* request, grpc_millis deadline, grpc_closure* on_done, grpc_httpcli_response* response); /* Asynchronously perform a HTTP POST. 'context' specifies the http context under which to do the post - 'pollset' indicates a grpc_pollset that is interested in the result - of the post - work on this pollset may be used to progress the post + 'pollent' indicates a grpc_polling_entity that is interested in the result + of the post - work on this entity may be used to progress the post operation - 'resource_quota' - this function takes ownership of a ref from the caller. + 'resource_quota' allows the caller to specify the quota against which to + allocate 'request' contains request parameters - these are caller owned and can be destroyed once the call returns 'body_bytes' and 'body_size' specify the payload for the post. @@ -104,7 +106,7 @@ void grpc_httpcli_get(grpc_httpcli_context* context, Does not support ?var1=val1&var2=val2 in the path. */ void grpc_httpcli_post(grpc_httpcli_context* context, grpc_polling_entity* pollent, - grpc_resource_quota* resource_quota, + grpc_core::ResourceQuotaRefPtr resource_quota, const grpc_httpcli_request* request, const char* body_bytes, size_t body_size, grpc_millis deadline, grpc_closure* on_done, diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 2a0108369df..ce66f6fa553 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -29,7 +29,6 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/pollset_set.h" -#include "src/core/lib/iomgr/resource_quota.h" /* An endpoint caps a streaming channel between two communicating processes. Examples may be: a tcp socket, , or some shared memory. */ diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 224e2766bd3..599f34aa200 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -59,10 +59,8 @@ struct CFStreamEndpoint { std::string peer_string; std::string local_address; - grpc_slice_allocator* slice_allocator; }; static void CFStreamFree(CFStreamEndpoint* ep) { - grpc_slice_allocator_destroy(ep->slice_allocator); CFRelease(ep->read_stream); CFRelease(ep->write_stream); CFSTREAM_HANDLE_UNREF(ep->stream_sync, "free"); @@ -238,17 +236,6 @@ static void WriteAction(void* arg, grpc_error_handle error) { grpc_slice_unref_internal(slice); } -static void CFStreamReadAllocationDone(void* arg, grpc_error_handle error) { - CFStreamEndpoint* ep = static_cast(arg); - if (error == GRPC_ERROR_NONE) { - ep->stream_sync->NotifyOnRead(&ep->read_action); - } else { - grpc_slice_buffer_reset_and_unref_internal(ep->read_slices); - CallReadCb(ep, error); - EP_UNREF(ep, "read"); - } -} - static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, bool urgent) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); @@ -260,13 +247,10 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, ep_impl->read_cb = cb; ep_impl->read_slices = slices; grpc_slice_buffer_reset_and_unref_internal(slices); + grpc_slice_buffer_add_indexed( + slices, GRPC_SLICE_MALLOC(GRPC_TCP_DEFAULT_READ_SLICE_SIZE)); EP_REF(ep_impl, "read"); - if (grpc_slice_allocator_allocate( - ep_impl->slice_allocator, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1, - grpc_slice_allocator_intent::kReadBuffer, ep_impl->read_slices, - CFStreamReadAllocationDone, ep_impl)) { - ep_impl->stream_sync->NotifyOnRead(&ep_impl->read_action); - } + ep_impl->stream_sync->NotifyOnRead(&ep_impl->read_action); } static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, @@ -337,10 +321,10 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead, CFStreamGetFD, CFStreamCanTrackErr}; -grpc_endpoint* grpc_cfstream_endpoint_create( - CFReadStreamRef read_stream, CFWriteStreamRef write_stream, - const char* peer_string, grpc_slice_allocator* slice_allocator, - CFStreamHandle* stream_sync) { +grpc_endpoint* grpc_cfstream_endpoint_create(CFReadStreamRef read_stream, + CFWriteStreamRef write_stream, + const char* peer_string, + CFStreamHandle* stream_sync) { CFStreamEndpoint* ep_impl = new CFStreamEndpoint; if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, @@ -381,7 +365,6 @@ grpc_endpoint* grpc_cfstream_endpoint_create( static_cast(ep_impl), grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&ep_impl->write_action, WriteAction, static_cast(ep_impl), grpc_schedule_on_exec_ctx); - ep_impl->slice_allocator = slice_allocator; return &ep_impl->base; } diff --git a/src/core/lib/iomgr/endpoint_cfstream.h b/src/core/lib/iomgr/endpoint_cfstream.h index 671bb3b2cef..6f2cf1c6e02 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.h +++ b/src/core/lib/iomgr/endpoint_cfstream.h @@ -39,10 +39,10 @@ #include "src/core/lib/iomgr/cfstream_handle.h" #include "src/core/lib/iomgr/endpoint.h" -grpc_endpoint* grpc_cfstream_endpoint_create( - CFReadStreamRef read_stream, CFWriteStreamRef write_stream, - const char* peer_string, grpc_slice_allocator* slice_allocator, - CFStreamHandle* stream_sync); +grpc_endpoint* grpc_cfstream_endpoint_create(CFReadStreamRef read_stream, + CFWriteStreamRef write_stream, + const char* peer_string, + CFStreamHandle* stream_sync); #endif /* GRPC_CFSTREAM */ diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 217ea3770f8..e45401a2208 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -40,6 +40,7 @@ #include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/iomgr/tcp_posix.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/resource_quota/api.h" static void create_sockets(int sv[2]) { int flags; @@ -59,18 +60,13 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, create_sockets(sv); grpc_core::ExecCtx exec_ctx; std::string final_name = absl::StrCat(name, ":client"); - grpc_resource_quota* resource_quota = - grpc_resource_quota_from_channel_args(args, true); - p.client = grpc_tcp_create( - grpc_fd_create(sv[1], final_name.c_str(), false), args, - "socketpair-server", - grpc_slice_allocator_create(resource_quota, "server_endpoint", args)); + args = grpc_core::EnsureResourceQuotaInChannelArgs(args); + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name.c_str(), false), + args, "socketpair-server"); final_name = absl::StrCat(name, ":server"); - p.server = grpc_tcp_create( - grpc_fd_create(sv[0], final_name.c_str(), false), args, - "socketpair-client", - grpc_slice_allocator_create(resource_quota, "client_endpoint", args)); - grpc_resource_quota_unref_internal(resource_quota); + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name.c_str(), false), + args, "socketpair-client"); + grpc_channel_args_destroy(args); return p; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index c1d34fae191..386057b8951 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -71,24 +71,15 @@ static void create_sockets(SOCKET sv[2]) { } grpc_endpoint_pair grpc_iomgr_create_endpoint_pair( - const char* name, grpc_channel_args* channel_args) { + const char*, grpc_channel_args* channel_args) { SOCKET sv[2]; grpc_endpoint_pair p; create_sockets(sv); grpc_core::ExecCtx exec_ctx; - grpc_resource_quota* resource_quota = - grpc_resource_quota_from_channel_args(channel_args, true); - p.client = - grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"), - channel_args, "endpoint:server", - grpc_slice_allocator_create( - resource_quota, "endpoint:server", channel_args)); - p.server = - grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"), - channel_args, "endpoint:client", - grpc_slice_allocator_create( - resource_quota, "endpoint:client", channel_args)); - grpc_resource_quota_unref_internal(resource_quota); + p.client = grpc_tcp_create(grpc_winsocket_create(sv[1], "endpoint:client"), + channel_args, "endpoint:server"); + p.server = grpc_tcp_create(grpc_winsocket_create(sv[0], "endpoint:server"), + channel_args, "endpoint:client"); return p; } diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc deleted file mode 100644 index 9f1ed409cc2..00000000000 --- a/src/core/lib/iomgr/resource_quota.cc +++ /dev/null @@ -1,1106 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/lib/iomgr/resource_quota.h" - -#include -#include -#include -#include - -#include - -#include "absl/strings/str_cat.h" - -#include -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/iomgr/combiner.h" -#include "src/core/lib/slice/slice_internal.h" - -grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota"); - -#define MEMORY_USAGE_ESTIMATION_MAX 65536 - -/* Internal linked list pointers for a resource user */ -struct grpc_resource_user_link { - grpc_resource_user* next; - grpc_resource_user* prev; -}; -/* Resource users are kept in (potentially) several intrusive linked lists - at once. These are the list names. */ -typedef enum { - /* Resource users that are waiting for an allocation */ - GRPC_RULIST_AWAITING_ALLOCATION, - /* Resource users that have free memory available for internal reclamation */ - GRPC_RULIST_NON_EMPTY_FREE_POOL, - /* Resource users that have published a benign reclamation is available */ - GRPC_RULIST_RECLAIMER_BENIGN, - /* Resource users that have published a destructive reclamation is - available */ - GRPC_RULIST_RECLAIMER_DESTRUCTIVE, - /* Number of lists: must be last */ - GRPC_RULIST_COUNT -} grpc_rulist; - -struct grpc_resource_user { - /* The quota this resource user consumes from */ - grpc_resource_quota* resource_quota; - - /* Closure to schedule an allocation under the resource quota combiner lock */ - grpc_closure allocate_closure; - /* Closure to publish a non empty free pool under the resource quota combiner - lock */ - grpc_closure add_to_free_pool_closure; - - /* one ref for each ref call (released by grpc_resource_user_unref), and one - ref for each byte allocated (released by grpc_resource_user_free) */ - gpr_atm refs; - /* is this resource user unlocked? starts at 0, increases for each shutdown - call */ - gpr_atm shutdown; - - gpr_mu mu; - /* The amount of memory (in bytes) this user has cached for its own use: to - avoid quota contention, each resource user can keep some memory in - addition to what it is immediately using (e.g., for caching), and the quota - can pull it back under memory pressure. - This value can become negative if more memory has been requested than - existed in the free pool, at which point the quota is consulted to bring - this value non-negative (asynchronously). */ - int64_t free_pool; - /* A list of closures to call once free_pool becomes non-negative - ie when - all outstanding allocations have been granted. */ - grpc_closure_list on_allocated; - /* True if we are currently trying to allocate from the quota, false if not */ - bool allocating; - /* The amount of memory (in bytes) that has been requested from this user - * asynchronously but hasn't been granted yet. */ - int64_t outstanding_allocations; - /* True if we are currently trying to add ourselves to the non-free quota - list, false otherwise */ - bool added_to_free_pool; - - /* The number of threads currently allocated to this resource user */ - gpr_atm num_threads_allocated; - - /* Reclaimers: index 0 is the benign reclaimer, 1 is the destructive reclaimer - */ - grpc_closure* reclaimers[2]; - /* Reclaimers just posted: once we're in the combiner lock, we'll move them - to the array above */ - grpc_closure* new_reclaimers[2]; - /* Trampoline closures to finish reclamation and re-enter the quota combiner - lock */ - grpc_closure post_reclaimer_closure[2]; - - /* Closure to execute under the quota combiner to de-register and shutdown the - resource user */ - grpc_closure destroy_closure; - - /* Links in the various grpc_rulist lists */ - grpc_resource_user_link links[GRPC_RULIST_COUNT]; - - /* The name of this resource user, for debugging/tracing */ - std::string name; -}; - -struct grpc_resource_quota { - /* refcount */ - gpr_refcount refs; - - /* estimate of current memory usage - scaled to the range [0..RESOURCE_USAGE_ESTIMATION_MAX] */ - gpr_atm memory_usage_estimation; - - /* Main combiner lock: all activity on a quota executes under this combiner - * (so no mutex is needed for this data structure) */ - grpc_core::Combiner* combiner; - /* Size of the resource quota */ - int64_t size; - /* Amount of free memory in the resource quota */ - int64_t free_pool; - /* Used size of memory in the resource quota. Updated as soon as the resource - * users start to allocate or free the memory. */ - gpr_atm used; - - gpr_atm last_size; - - /* Mutex to protect max_threads and num_threads_allocated */ - /* Note: We could have used gpr_atm for max_threads and num_threads_allocated - * and avoid having this mutex; but in that case, each invocation of the - * function grpc_resource_user_allocate_threads() would have had to do at - * least two atomic loads (for max_threads and num_threads_allocated) followed - * by a CAS (on num_threads_allocated). - * Moreover, we expect grpc_resource_user_allocate_threads() to be often - * called concurrently thereby increasing the chances of failing the CAS - * operation. This additional complexity is not worth the tiny perf gain we - * may (or may not) have by using atomics */ - gpr_mu thread_count_mu; - - /* Max number of threads allowed */ - int max_threads; - - /* Number of threads currently allocated via this resource_quota object */ - int num_threads_allocated; - - /* Has rq_step been scheduled to occur? */ - bool step_scheduled; - - /* Are we currently reclaiming memory */ - bool reclaiming; - - /* Closure around rq_step */ - grpc_closure rq_step_closure; - - /* Closure around rq_reclamation_done */ - grpc_closure rq_reclamation_done_closure; - - /* This is only really usable for debugging: it's always a stale pointer, but - a stale pointer that might just be fresh enough to guide us to where the - reclamation system is stuck */ - grpc_closure* debug_only_last_initiated_reclaimer; - grpc_resource_user* debug_only_last_reclaimer_resource_user; - - /* Roots of all resource user lists */ - grpc_resource_user* roots[GRPC_RULIST_COUNT]; - - std::string name; -}; - -static void ru_unref_by(grpc_resource_user* resource_user, gpr_atm amount); - -/******************************************************************************* - * list management - */ - -static void rulist_add_head(grpc_resource_user* resource_user, - grpc_rulist list) { - grpc_resource_quota* resource_quota = resource_user->resource_quota; - grpc_resource_user** root = &resource_quota->roots[list]; - if (*root == nullptr) { - *root = resource_user; - resource_user->links[list].next = resource_user->links[list].prev = - resource_user; - } else { - resource_user->links[list].next = *root; - resource_user->links[list].prev = (*root)->links[list].prev; - resource_user->links[list].next->links[list].prev = - resource_user->links[list].prev->links[list].next = resource_user; - *root = resource_user; - } -} - -static void rulist_add_tail(grpc_resource_user* resource_user, - grpc_rulist list) { - grpc_resource_quota* resource_quota = resource_user->resource_quota; - grpc_resource_user** root = &resource_quota->roots[list]; - if (*root == nullptr) { - *root = resource_user; - resource_user->links[list].next = resource_user->links[list].prev = - resource_user; - } else { - resource_user->links[list].next = (*root)->links[list].next; - resource_user->links[list].prev = *root; - resource_user->links[list].next->links[list].prev = - resource_user->links[list].prev->links[list].next = resource_user; - } -} - -static bool rulist_empty(grpc_resource_quota* resource_quota, - grpc_rulist list) { - return resource_quota->roots[list] == nullptr; -} - -static grpc_resource_user* rulist_pop_head(grpc_resource_quota* resource_quota, - grpc_rulist list) { - grpc_resource_user** root = &resource_quota->roots[list]; - grpc_resource_user* resource_user = *root; - if (resource_user == nullptr) { - return nullptr; - } - if (resource_user->links[list].next == resource_user) { - *root = nullptr; - } else { - resource_user->links[list].next->links[list].prev = - resource_user->links[list].prev; - resource_user->links[list].prev->links[list].next = - resource_user->links[list].next; - *root = resource_user->links[list].next; - } - resource_user->links[list].next = resource_user->links[list].prev = nullptr; - return resource_user; -} - -static void rulist_remove(grpc_resource_user* resource_user, grpc_rulist list) { - if (resource_user->links[list].next == nullptr) return; - grpc_resource_quota* resource_quota = resource_user->resource_quota; - if (resource_quota->roots[list] == resource_user) { - resource_quota->roots[list] = resource_user->links[list].next; - if (resource_quota->roots[list] == resource_user) { - resource_quota->roots[list] = nullptr; - } - } - resource_user->links[list].next->links[list].prev = - resource_user->links[list].prev; - resource_user->links[list].prev->links[list].next = - resource_user->links[list].next; - resource_user->links[list].next = resource_user->links[list].prev = nullptr; -} - -/******************************************************************************* - * resource quota state machine - */ - -static bool rq_alloc(grpc_resource_quota* resource_quota); -static bool rq_reclaim_from_per_user_free_pool( - grpc_resource_quota* resource_quota); -static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive); - -static void rq_step(void* rq, grpc_error_handle /*error*/) { - grpc_resource_quota* resource_quota = static_cast(rq); - resource_quota->step_scheduled = false; - do { - if (rq_alloc(resource_quota)) goto done; - } while (rq_reclaim_from_per_user_free_pool(resource_quota)); - - if (!rq_reclaim(resource_quota, false)) { - rq_reclaim(resource_quota, true); - } - -done: - grpc_resource_quota_unref_internal(resource_quota); -} - -static void rq_step_sched(grpc_resource_quota* resource_quota) { - if (resource_quota->step_scheduled) return; - resource_quota->step_scheduled = true; - grpc_resource_quota_ref_internal(resource_quota); - resource_quota->combiner->FinallyRun(&resource_quota->rq_step_closure, - GRPC_ERROR_NONE); -} - -/* update the atomically available resource estimate - use no barriers since - timeliness of delivery really doesn't matter much */ -static void rq_update_estimate(grpc_resource_quota* resource_quota) { - gpr_atm memory_usage_estimation = MEMORY_USAGE_ESTIMATION_MAX; - if (resource_quota->size != 0) { - memory_usage_estimation = grpc_core::Clamp( - static_cast( - (1.0 - (static_cast(resource_quota->free_pool)) / - (static_cast(resource_quota->size))) * - MEMORY_USAGE_ESTIMATION_MAX), - gpr_atm(0), gpr_atm(MEMORY_USAGE_ESTIMATION_MAX)); - } - gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, - memory_usage_estimation); -} - -/* returns true if all allocations are completed */ -static bool rq_alloc(grpc_resource_quota* resource_quota) { - grpc_resource_user* resource_user; - while ((resource_user = rulist_pop_head(resource_quota, - GRPC_RULIST_AWAITING_ALLOCATION))) { - gpr_mu_lock(&resource_user->mu); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, - "RQ: check allocation for user %p shutdown=%" PRIdPTR - " free_pool=%" PRId64 " outstanding_allocations=%" PRId64, - resource_user, gpr_atm_no_barrier_load(&resource_user->shutdown), - resource_user->free_pool, resource_user->outstanding_allocations); - } - if (gpr_atm_no_barrier_load(&resource_user->shutdown)) { - resource_user->allocating = false; - grpc_closure_list_fail_all( - &resource_user->on_allocated, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource user shutdown")); - int64_t aborted_allocations = resource_user->outstanding_allocations; - resource_user->outstanding_allocations = 0; - resource_user->free_pool += aborted_allocations; - grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &resource_user->on_allocated); - gpr_mu_unlock(&resource_user->mu); - if (aborted_allocations > 0) { - ru_unref_by(resource_user, static_cast(aborted_allocations)); - } - continue; - } - if (resource_user->free_pool < 0 && - -resource_user->free_pool <= resource_quota->free_pool) { - int64_t amt = -resource_user->free_pool; - resource_user->free_pool = 0; - resource_quota->free_pool -= amt; - rq_update_estimate(resource_quota); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, - "RQ %s %s: grant alloc %" PRId64 - " bytes; rq_free_pool -> %" PRId64, - resource_quota->name.c_str(), resource_user->name.c_str(), amt, - resource_quota->free_pool); - } - } else if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace) && - resource_user->free_pool >= 0) { - gpr_log(GPR_INFO, "RQ %s %s: discard already satisfied alloc request", - resource_quota->name.c_str(), resource_user->name.c_str()); - } - if (resource_user->free_pool >= 0) { - resource_user->allocating = false; - resource_user->outstanding_allocations = 0; - grpc_core::ExecCtx::RunList(DEBUG_LOCATION, &resource_user->on_allocated); - gpr_mu_unlock(&resource_user->mu); - } else { - rulist_add_head(resource_user, GRPC_RULIST_AWAITING_ALLOCATION); - gpr_mu_unlock(&resource_user->mu); - return false; - } - } - return true; -} - -/* returns true if any memory could be reclaimed from buffers */ -static bool rq_reclaim_from_per_user_free_pool( - grpc_resource_quota* resource_quota) { - grpc_resource_user* resource_user; - while ((resource_user = rulist_pop_head(resource_quota, - GRPC_RULIST_NON_EMPTY_FREE_POOL))) { - gpr_mu_lock(&resource_user->mu); - resource_user->added_to_free_pool = false; - if (resource_user->free_pool > 0) { - int64_t amt = resource_user->free_pool; - resource_user->free_pool = 0; - resource_quota->free_pool += amt; - rq_update_estimate(resource_quota); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, - "RQ %s %s: reclaim_from_per_user_free_pool %" PRId64 - " bytes; rq_free_pool -> %" PRId64, - resource_quota->name.c_str(), resource_user->name.c_str(), amt, - resource_quota->free_pool); - } - gpr_mu_unlock(&resource_user->mu); - return true; - } else { - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, - "RQ %s %s: failed to reclaim_from_per_user_free_pool; " - "free_pool = %" PRId64 "; rq_free_pool = %" PRId64, - resource_quota->name.c_str(), resource_user->name.c_str(), - resource_user->free_pool, resource_quota->free_pool); - } - gpr_mu_unlock(&resource_user->mu); - } - } - return false; -} - -/* returns true if reclamation is proceeding */ -static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) { - if (resource_quota->reclaiming) return true; - grpc_rulist list = destructive ? GRPC_RULIST_RECLAIMER_DESTRUCTIVE - : GRPC_RULIST_RECLAIMER_BENIGN; - grpc_resource_user* resource_user = rulist_pop_head(resource_quota, list); - if (resource_user == nullptr) return false; - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RQ %s %s: initiate %s reclamation", - resource_quota->name.c_str(), resource_user->name.c_str(), - destructive ? "destructive" : "benign"); - } - resource_quota->reclaiming = true; - grpc_resource_quota_ref_internal(resource_quota); - grpc_closure* c = resource_user->reclaimers[destructive]; - GPR_ASSERT(c); - resource_quota->debug_only_last_reclaimer_resource_user = resource_user; - resource_quota->debug_only_last_initiated_reclaimer = c; - resource_user->reclaimers[destructive] = nullptr; - grpc_core::ExecCtx::Run(DEBUG_LOCATION, c, GRPC_ERROR_NONE); - return true; -} - -/******************************************************************************* - * ru_slice: a slice implementation that is backed by a grpc_resource_user - */ - -namespace grpc_core { - -class RuSliceRefcount { - public: - static void Destroy(void* p) { - auto* rc = static_cast(p); - rc->~RuSliceRefcount(); - gpr_free(rc); - } - RuSliceRefcount(grpc_resource_user* resource_user, size_t size) - : base_(grpc_slice_refcount::Type::REGULAR, &refs_, Destroy, this, - &base_), - resource_user_(resource_user), - size_(size) { - // Nothing to do here. - } - ~RuSliceRefcount() { grpc_resource_user_free(resource_user_, size_); } - - grpc_slice_refcount* base_refcount() { return &base_; } - - private: - grpc_slice_refcount base_; - RefCount refs_; - grpc_resource_user* resource_user_; - size_t size_; -}; - -} // namespace grpc_core - -static grpc_slice ru_slice_create(grpc_resource_user* resource_user, - size_t size) { - auto* rc = static_cast( - gpr_malloc(sizeof(grpc_core::RuSliceRefcount) + size)); - new (rc) grpc_core::RuSliceRefcount(resource_user, size); - grpc_slice slice; - - slice.refcount = rc->base_refcount(); - slice.data.refcounted.bytes = reinterpret_cast(rc + 1); - slice.data.refcounted.length = size; - return slice; -} - -/******************************************************************************* - * grpc_resource_quota internal implementation: resource user manipulation under - * the combiner - */ - -// TODO(hork): rename all ru variables to resource_user -static void ru_allocate(void* ru, grpc_error_handle /*error*/) { - grpc_resource_user* resource_user = static_cast(ru); - if (rulist_empty(resource_user->resource_quota, - GRPC_RULIST_AWAITING_ALLOCATION)) { - rq_step_sched(resource_user->resource_quota); - } - rulist_add_tail(resource_user, GRPC_RULIST_AWAITING_ALLOCATION); -} - -static void ru_add_to_free_pool(void* ru, grpc_error_handle /*error*/) { - grpc_resource_user* resource_user = static_cast(ru); - if (!rulist_empty(resource_user->resource_quota, - GRPC_RULIST_AWAITING_ALLOCATION) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_NON_EMPTY_FREE_POOL)) { - rq_step_sched(resource_user->resource_quota); - } - rulist_add_tail(resource_user, GRPC_RULIST_NON_EMPTY_FREE_POOL); -} - -static bool ru_post_reclaimer(grpc_resource_user* resource_user, - bool destructive) { - grpc_closure* closure = resource_user->new_reclaimers[destructive]; - GPR_ASSERT(closure != nullptr); - resource_user->new_reclaimers[destructive] = nullptr; - GPR_ASSERT(resource_user->reclaimers[destructive] == nullptr); - if (gpr_atm_acq_load(&resource_user->shutdown) > 0) { - grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, GRPC_ERROR_CANCELLED); - return false; - } - resource_user->reclaimers[destructive] = closure; - return true; -} - -static void ru_post_benign_reclaimer(void* ru, grpc_error_handle /*error*/) { - grpc_resource_user* resource_user = static_cast(ru); - if (!ru_post_reclaimer(resource_user, false)) return; - if (!rulist_empty(resource_user->resource_quota, - GRPC_RULIST_AWAITING_ALLOCATION) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_NON_EMPTY_FREE_POOL) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_RECLAIMER_BENIGN)) { - rq_step_sched(resource_user->resource_quota); - } - rulist_add_tail(resource_user, GRPC_RULIST_RECLAIMER_BENIGN); -} - -static void ru_post_destructive_reclaimer(void* ru, - grpc_error_handle /*error*/) { - grpc_resource_user* resource_user = static_cast(ru); - if (!ru_post_reclaimer(resource_user, true)) return; - if (!rulist_empty(resource_user->resource_quota, - GRPC_RULIST_AWAITING_ALLOCATION) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_NON_EMPTY_FREE_POOL) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_RECLAIMER_BENIGN) && - rulist_empty(resource_user->resource_quota, - GRPC_RULIST_RECLAIMER_DESTRUCTIVE)) { - rq_step_sched(resource_user->resource_quota); - } - rulist_add_tail(resource_user, GRPC_RULIST_RECLAIMER_DESTRUCTIVE); -} - -static void ru_shutdown(void* ru, grpc_error_handle /*error*/) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RU shutdown %p", ru); - } - grpc_resource_user* resource_user = static_cast(ru); - gpr_mu_lock(&resource_user->mu); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, resource_user->reclaimers[0], - GRPC_ERROR_CANCELLED); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, resource_user->reclaimers[1], - GRPC_ERROR_CANCELLED); - resource_user->reclaimers[0] = nullptr; - resource_user->reclaimers[1] = nullptr; - rulist_remove(resource_user, GRPC_RULIST_RECLAIMER_BENIGN); - rulist_remove(resource_user, GRPC_RULIST_RECLAIMER_DESTRUCTIVE); - if (resource_user->allocating) { - rq_step_sched(resource_user->resource_quota); - } - gpr_mu_unlock(&resource_user->mu); -} - -static void ru_destroy(void* ru, grpc_error_handle /*error*/) { - grpc_resource_user* resource_user = static_cast(ru); - GPR_ASSERT(gpr_atm_no_barrier_load(&resource_user->refs) == 0); - // Free all the remaining thread quota - grpc_resource_user_free_threads(resource_user, - static_cast(gpr_atm_no_barrier_load( - &resource_user->num_threads_allocated))); - - for (int i = 0; i < GRPC_RULIST_COUNT; i++) { - rulist_remove(resource_user, static_cast(i)); - } - grpc_core::ExecCtx::Run(DEBUG_LOCATION, resource_user->reclaimers[0], - GRPC_ERROR_CANCELLED); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, resource_user->reclaimers[1], - GRPC_ERROR_CANCELLED); - if (resource_user->free_pool != 0) { - resource_user->resource_quota->free_pool += resource_user->free_pool; - rq_step_sched(resource_user->resource_quota); - } - grpc_resource_quota_unref_internal(resource_user->resource_quota); - gpr_mu_destroy(&resource_user->mu); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RU '%s' (%p) destroyed", resource_user->name.c_str(), - resource_user); - } - delete resource_user; -} - -static void ru_alloc_slices(grpc_slice_allocator* slice_allocator) { - for (size_t i = 0; i < slice_allocator->count; i++) { - grpc_slice_buffer_add_indexed( - slice_allocator->dest, ru_slice_create(slice_allocator->resource_user, - slice_allocator->length)); - } -} - -static void ru_allocated_slices(void* arg, grpc_error_handle error) { - grpc_slice_allocator* slice_allocator = - static_cast(arg); - if (error == GRPC_ERROR_NONE) ru_alloc_slices(slice_allocator); - grpc_core::Closure::Run(DEBUG_LOCATION, &slice_allocator->on_done, - GRPC_ERROR_REF(error)); -} - -/******************************************************************************* - * grpc_resource_quota internal implementation: quota manipulation under the - * combiner - */ - -struct rq_resize_args { - int64_t size; - grpc_resource_quota* resource_quota; - grpc_closure closure; -}; -static void rq_resize(void* args, grpc_error_handle /*error*/) { - rq_resize_args* a = static_cast(args); - int64_t delta = a->size - a->resource_quota->size; - a->resource_quota->size += delta; - a->resource_quota->free_pool += delta; - rq_update_estimate(a->resource_quota); - rq_step_sched(a->resource_quota); - grpc_resource_quota_unref_internal(a->resource_quota); - gpr_free(a); -} - -static void rq_reclamation_done(void* rq, grpc_error_handle /*error*/) { - grpc_resource_quota* resource_quota = static_cast(rq); - resource_quota->reclaiming = false; - rq_step_sched(resource_quota); - grpc_resource_quota_unref_internal(resource_quota); -} - -/******************************************************************************* - * grpc_resource_quota api - */ - -/* Public API */ -grpc_resource_quota* grpc_resource_quota_create(const char* name) { - grpc_resource_quota* resource_quota = new grpc_resource_quota; - gpr_ref_init(&resource_quota->refs, 1); - resource_quota->combiner = grpc_combiner_create(); - resource_quota->free_pool = INT64_MAX; - resource_quota->size = INT64_MAX; - resource_quota->used = 0; - gpr_atm_no_barrier_store(&resource_quota->last_size, GPR_ATM_MAX); - gpr_mu_init(&resource_quota->thread_count_mu); - resource_quota->max_threads = INT_MAX; - resource_quota->num_threads_allocated = 0; - resource_quota->step_scheduled = false; - resource_quota->reclaiming = false; - gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0); - if (name != nullptr) { - resource_quota->name = name; - } else { - resource_quota->name = absl::StrCat( - "anonymous_pool_", reinterpret_cast(resource_quota)); - } - GRPC_CLOSURE_INIT(&resource_quota->rq_step_closure, rq_step, resource_quota, - nullptr); - GRPC_CLOSURE_INIT(&resource_quota->rq_reclamation_done_closure, - rq_reclamation_done, resource_quota, nullptr); - for (int i = 0; i < GRPC_RULIST_COUNT; i++) { - resource_quota->roots[i] = nullptr; - } - return resource_quota; -} - -void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota) { - if (gpr_unref(&resource_quota->refs)) { - // No outstanding thread quota - GPR_ASSERT(resource_quota->num_threads_allocated == 0); - GRPC_COMBINER_UNREF(resource_quota->combiner, "resource_quota"); - gpr_mu_destroy(&resource_quota->thread_count_mu); - delete resource_quota; - } -} - -/* Public API */ -void grpc_resource_quota_unref(grpc_resource_quota* resource_quota) { - grpc_core::ExecCtx exec_ctx; - grpc_resource_quota_unref_internal(resource_quota); -} - -grpc_resource_quota* grpc_resource_quota_ref_internal( - grpc_resource_quota* resource_quota) { - gpr_ref(&resource_quota->refs); - return resource_quota; -} - -/* Public API */ -void grpc_resource_quota_ref(grpc_resource_quota* resource_quota) { - grpc_resource_quota_ref_internal(resource_quota); -} - -double grpc_resource_quota_get_memory_pressure( - grpc_resource_quota* resource_quota) { - return (static_cast(gpr_atm_no_barrier_load( - &resource_quota->memory_usage_estimation))) / - (static_cast(MEMORY_USAGE_ESTIMATION_MAX)); -} - -/* Public API */ -void grpc_resource_quota_set_max_threads(grpc_resource_quota* resource_quota, - int new_max_threads) { - GPR_ASSERT(new_max_threads >= 0); - gpr_mu_lock(&resource_quota->thread_count_mu); - resource_quota->max_threads = new_max_threads; - gpr_mu_unlock(&resource_quota->thread_count_mu); -} - -/* Public API */ -void grpc_resource_quota_resize(grpc_resource_quota* resource_quota, - size_t size) { - grpc_core::ExecCtx exec_ctx; - rq_resize_args* a = static_cast(gpr_malloc(sizeof(*a))); - a->resource_quota = grpc_resource_quota_ref_internal(resource_quota); - a->size = static_cast(size); - gpr_atm_no_barrier_store(&resource_quota->last_size, - (gpr_atm)std::min((size_t)GPR_ATM_MAX, size)); - GRPC_CLOSURE_INIT(&a->closure, rq_resize, a, grpc_schedule_on_exec_ctx); - grpc_core::ExecCtx::Run(DEBUG_LOCATION, &a->closure, GRPC_ERROR_NONE); -} - -size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota) { - return static_cast( - gpr_atm_no_barrier_load(&resource_quota->last_size)); -} - -/******************************************************************************* - * grpc_resource_user channel args api - */ - -grpc_resource_quota* grpc_resource_quota_from_channel_args( - const grpc_channel_args* channel_args, bool create) { - auto* resource_quota = grpc_channel_args_find_pointer( - channel_args, GRPC_ARG_RESOURCE_QUOTA); - if (resource_quota != nullptr) { - return grpc_resource_quota_ref_internal(resource_quota); - } - return create ? grpc_resource_quota_create(nullptr) : nullptr; -} - -static void* rq_copy(void* rq) { - grpc_resource_quota_ref(static_cast(rq)); - return rq; -} - -static void rq_destroy(void* rq) { - grpc_resource_quota_unref_internal(static_cast(rq)); -} - -static int rq_cmp(void* a, void* b) { return grpc_core::QsortCompare(a, b); } - -const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void) { - static const grpc_arg_pointer_vtable vtable = {rq_copy, rq_destroy, rq_cmp}; - return &vtable; -} - -/******************************************************************************* - * grpc_resource_user api - */ - -grpc_resource_user* grpc_resource_user_create( - grpc_resource_quota* resource_quota, absl::string_view name) { - grpc_resource_user* resource_user = new grpc_resource_user; - resource_user->resource_quota = - grpc_resource_quota_ref_internal(resource_quota); - GRPC_CLOSURE_INIT(&resource_user->allocate_closure, &ru_allocate, - resource_user, nullptr); - GRPC_CLOSURE_INIT(&resource_user->add_to_free_pool_closure, - &ru_add_to_free_pool, resource_user, nullptr); - GRPC_CLOSURE_INIT(&resource_user->post_reclaimer_closure[0], - &ru_post_benign_reclaimer, resource_user, nullptr); - GRPC_CLOSURE_INIT(&resource_user->post_reclaimer_closure[1], - &ru_post_destructive_reclaimer, resource_user, nullptr); - GRPC_CLOSURE_INIT(&resource_user->destroy_closure, &ru_destroy, resource_user, - nullptr); - gpr_mu_init(&resource_user->mu); - gpr_atm_rel_store(&resource_user->refs, 1); - gpr_atm_rel_store(&resource_user->shutdown, 0); - resource_user->free_pool = 0; - grpc_closure_list_init(&resource_user->on_allocated); - resource_user->allocating = false; - resource_user->added_to_free_pool = false; - gpr_atm_no_barrier_store(&resource_user->num_threads_allocated, 0); - resource_user->reclaimers[0] = nullptr; - resource_user->reclaimers[1] = nullptr; - resource_user->new_reclaimers[0] = nullptr; - resource_user->new_reclaimers[1] = nullptr; - resource_user->outstanding_allocations = 0; - for (int i = 0; i < GRPC_RULIST_COUNT; i++) { - resource_user->links[i].next = resource_user->links[i].prev = nullptr; - } - if (!name.empty()) { - resource_user->name = std::string(name); - } else { - resource_user->name = absl::StrCat( - "anonymous_resource_user_", reinterpret_cast(resource_user)); - } - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RU '%s' (%p) created", resource_user->name.c_str(), - resource_user); - } - return resource_user; -} - -grpc_resource_quota* grpc_resource_user_quota( - grpc_resource_user* resource_user) { - return resource_user->resource_quota; -} - -static void ru_ref_by(grpc_resource_user* resource_user, gpr_atm amount) { - GPR_ASSERT(amount > 0); - gpr_atm prior = gpr_atm_no_barrier_fetch_add(&resource_user->refs, amount); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RU '%s' (%p) reffing: %" PRIdPTR " -> %" PRIdPTR, - resource_user->name.c_str(), resource_user, prior, prior + amount); - } - GPR_ASSERT(prior != 0); -} - -static void ru_unref_by(grpc_resource_user* resource_user, gpr_atm amount) { - GPR_ASSERT(amount > 0); - gpr_atm old = gpr_atm_full_fetch_add(&resource_user->refs, -amount); - GPR_ASSERT(old >= amount); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RU '%s' (%p) unreffing: %" PRIdPTR " -> %" PRIdPTR, - resource_user->name.c_str(), resource_user, old, old - amount); - } - if (old == amount) { - resource_user->resource_quota->combiner->Run( - &resource_user->destroy_closure, GRPC_ERROR_NONE); - } -} - -void grpc_resource_user_ref(grpc_resource_user* resource_user) { - ru_ref_by(resource_user, 1); -} - -void grpc_resource_user_unref(grpc_resource_user* resource_user) { - ru_unref_by(resource_user, 1); -} - -void grpc_resource_user_shutdown(grpc_resource_user* resource_user) { - if (gpr_atm_full_fetch_add(&resource_user->shutdown, 1) == 0) { - resource_user->resource_quota->combiner->Run( - GRPC_CLOSURE_CREATE(ru_shutdown, resource_user, nullptr), - GRPC_ERROR_NONE); - } -} - -bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, - int thread_count) { - GPR_ASSERT(thread_count >= 0); - bool is_success = false; - gpr_mu_lock(&resource_user->resource_quota->thread_count_mu); - grpc_resource_quota* resource_quota = resource_user->resource_quota; - if (resource_quota->num_threads_allocated + thread_count <= - resource_quota->max_threads) { - resource_quota->num_threads_allocated += thread_count; - gpr_atm_no_barrier_fetch_add(&resource_user->num_threads_allocated, - thread_count); - is_success = true; - } - gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu); - return is_success; -} - -void grpc_resource_user_free_threads(grpc_resource_user* resource_user, - int thread_count) { - GPR_ASSERT(thread_count >= 0); - gpr_mu_lock(&resource_user->resource_quota->thread_count_mu); - grpc_resource_quota* resource_quota = resource_user->resource_quota; - resource_quota->num_threads_allocated -= thread_count; - int old_count = static_cast(gpr_atm_no_barrier_fetch_add( - &resource_user->num_threads_allocated, -thread_count)); - if (old_count < thread_count || resource_quota->num_threads_allocated < 0) { - gpr_log(GPR_ERROR, - "Releasing more threads (%d) than currently allocated " - "(resource_quota threads: %d, ru threads: %d)", - thread_count, resource_quota->num_threads_allocated + thread_count, - old_count); - abort(); - } - gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu); -} - -static bool resource_user_alloc_locked(grpc_resource_user* resource_user, - size_t size, - grpc_closure* optional_on_done) { - ru_ref_by(resource_user, static_cast(size)); - resource_user->free_pool -= static_cast(size); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RQ %s %s: alloc %" PRIdPTR "; free_pool -> %" PRId64, - resource_user->resource_quota->name.c_str(), - resource_user->name.c_str(), size, resource_user->free_pool); - } - if (GPR_LIKELY(resource_user->free_pool >= 0)) return true; - // Slow path: We need to wait for the free pool to refill. - if (optional_on_done != nullptr) { - resource_user->outstanding_allocations += static_cast(size); - grpc_closure_list_append(&resource_user->on_allocated, optional_on_done, - GRPC_ERROR_NONE); - } - if (!resource_user->allocating) { - resource_user->allocating = true; - resource_user->resource_quota->combiner->Run( - &resource_user->allocate_closure, GRPC_ERROR_NONE); - } - return false; -} - -bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user, - size_t size) { - if (gpr_atm_no_barrier_load(&resource_user->shutdown)) return false; - gpr_mu_lock(&resource_user->mu); - grpc_resource_quota* resource_quota = resource_user->resource_quota; - bool cas_success; - do { - gpr_atm used = gpr_atm_no_barrier_load(&resource_quota->used); - gpr_atm new_used = used + size; - if (static_cast(new_used) > - grpc_resource_quota_peek_size(resource_quota)) { - gpr_mu_unlock(&resource_user->mu); - return false; - } - cas_success = gpr_atm_full_cas(&resource_quota->used, used, new_used); - } while (!cas_success); - resource_user_alloc_locked(resource_user, size, nullptr); - gpr_mu_unlock(&resource_user->mu); - return true; -} - -bool grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, - grpc_closure* optional_on_done) { - // TODO(juanlishen): Maybe return immediately if shutting down. Deferring this - // because some tests become flaky after the change. - gpr_mu_lock(&resource_user->mu); - grpc_resource_quota* resource_quota = resource_user->resource_quota; - gpr_atm_no_barrier_fetch_add(&resource_quota->used, size); - const bool ret = - resource_user_alloc_locked(resource_user, size, optional_on_done); - gpr_mu_unlock(&resource_user->mu); - return ret; -} - -void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size) { - gpr_mu_lock(&resource_user->mu); - grpc_resource_quota* resource_quota = resource_user->resource_quota; - gpr_atm prior = gpr_atm_no_barrier_fetch_add(&resource_quota->used, -size); - GPR_ASSERT(prior >= static_cast(size)); - bool was_zero_or_negative = resource_user->free_pool <= 0; - resource_user->free_pool += static_cast(size); - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RQ %s %s: free %" PRIdPTR "; free_pool -> %" PRId64, - resource_user->resource_quota->name.c_str(), - resource_user->name.c_str(), size, resource_user->free_pool); - } - bool is_bigger_than_zero = resource_user->free_pool > 0; - if (is_bigger_than_zero && was_zero_or_negative && - !resource_user->added_to_free_pool) { - resource_user->added_to_free_pool = true; - resource_quota->combiner->Run(&resource_user->add_to_free_pool_closure, - GRPC_ERROR_NONE); - } - gpr_mu_unlock(&resource_user->mu); - ru_unref_by(resource_user, static_cast(size)); -} - -void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user, - bool destructive, - grpc_closure* closure) { - GPR_ASSERT(resource_user->new_reclaimers[destructive] == nullptr); - resource_user->new_reclaimers[destructive] = closure; - resource_user->resource_quota->combiner->Run( - &resource_user->post_reclaimer_closure[destructive], GRPC_ERROR_NONE); -} - -void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "RQ %s %s: reclamation complete", - resource_user->resource_quota->name.c_str(), - resource_user->name.c_str()); - } - resource_user->resource_quota->combiner->Run( - &resource_user->resource_quota->rq_reclamation_done_closure, - GRPC_ERROR_NONE); -} - -grpc_slice_allocator* grpc_slice_allocator_create( - grpc_resource_quota* resource_quota, absl::string_view name, - const grpc_channel_args* args) { - grpc_slice_allocator* slice_allocator = new grpc_slice_allocator; - slice_allocator->min_length = grpc_channel_args_find_integer( - args, GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE, - {GRPC_SLICE_ALLOCATOR_MIN_ALLOCATE_SIZE, -1, INT_MAX}); - slice_allocator->max_length = grpc_channel_args_find_integer( - args, GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE, - {GRPC_SLICE_ALLOCATOR_MAX_ALLOCATE_SIZE, -1, INT_MAX}); - slice_allocator->resource_user = - grpc_resource_user_create(resource_quota, name); - GRPC_CLOSURE_INIT(&slice_allocator->on_allocated, ru_allocated_slices, - slice_allocator, grpc_schedule_on_exec_ctx); - return slice_allocator; -} - -void grpc_slice_allocator_destroy(grpc_slice_allocator* slice_allocator) { - ru_unref_by(slice_allocator->resource_user, 1); - delete slice_allocator; -} - -static size_t grpc_slice_allocator_adjust_allocation_length( - grpc_slice_allocator* slice_allocator, size_t requested_length, - grpc_slice_allocator_intent intent) { - if (intent == grpc_slice_allocator_intent::kDefault) { - return requested_length; - } - GPR_ASSERT(intent == grpc_slice_allocator_intent::kReadBuffer); - double pressure = grpc_resource_quota_get_memory_pressure( - slice_allocator->resource_user->resource_quota); - // Reduce allocation size proportional to the pressure > 80% usage. - size_t target = - requested_length * (pressure > 0.8 ? (1.0 - pressure) / 0.2 : 1.0); - // Target will be some multiple of 8 bytes, rounded up - target = - (static_cast(grpc_core::Clamp(target, slice_allocator->min_length, - slice_allocator->max_length)) + - 255) & - ~static_cast(255); - // Don't use more than 1/16th of the overall resource quota for a single - // read alloc - size_t rqmax = grpc_resource_quota_peek_size( - slice_allocator->resource_user->resource_quota); - if (target > rqmax / 16 && rqmax > 1024) { - target = rqmax / 16; - } - if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log( - GPR_INFO, - "SliceAllocator(%p) requested %zu bytes for (%s) intent, adjusted " - "allocation size to %zu", - slice_allocator, requested_length, - intent == grpc_slice_allocator_intent::kDefault ? "default" : "read", - target); - } - return target; -} - -bool grpc_slice_allocator_allocate(grpc_slice_allocator* slice_allocator, - size_t length, size_t count, - grpc_slice_allocator_intent intent, - grpc_slice_buffer* dest, - grpc_iomgr_cb_func cb, void* p) { - if (GPR_UNLIKELY( - gpr_atm_no_barrier_load(&slice_allocator->resource_user->shutdown))) { - grpc_core::ExecCtx::Run( - DEBUG_LOCATION, &slice_allocator->on_allocated, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resource user shutdown")); - return false; - } - GRPC_CLOSURE_INIT(&slice_allocator->on_done, cb, p, - grpc_schedule_on_exec_ctx); - slice_allocator->length = grpc_slice_allocator_adjust_allocation_length( - slice_allocator, length, intent); - slice_allocator->count = count; - slice_allocator->dest = dest; - const bool ret = grpc_resource_user_alloc(slice_allocator->resource_user, - count * slice_allocator->length, - &slice_allocator->on_allocated); - if (ret) ru_alloc_slices(slice_allocator); - return ret; -} - -grpc_slice_allocator_factory* grpc_slice_allocator_factory_create( - grpc_resource_quota* resource_quota) { - grpc_slice_allocator_factory* factory = new grpc_slice_allocator_factory; - factory->resource_quota = resource_quota; - return factory; -} - -grpc_slice_allocator* grpc_slice_allocator_factory_create_slice_allocator( - grpc_slice_allocator_factory* slice_allocator_factory, - absl::string_view name, grpc_channel_args* args) { - return grpc_slice_allocator_create(slice_allocator_factory->resource_quota, - name, args); -} - -void grpc_slice_allocator_factory_destroy( - grpc_slice_allocator_factory* slice_allocator_factory) { - grpc_resource_quota_unref_internal(slice_allocator_factory->resource_quota); - delete slice_allocator_factory; -} diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h deleted file mode 100644 index aeb8259801f..00000000000 --- a/src/core/lib/iomgr/resource_quota.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H -#define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H - -#include - -#include - -#include "src/core/lib/debug/trace.h" -#include "src/core/lib/iomgr/closure.h" - -/** \file Tracks resource usage against a pool. - - The current implementation tracks only memory usage, but in the future - this may be extended to (for example) threads and file descriptors. - - A grpc_resource_quota represents the pooled resources, and - grpc_resource_user instances attach to the quota and consume those - resources. They also offer a vector for reclamation: if we become - resource constrained, grpc_resource_user instances are asked (in turn) to - free up whatever they can so that the system as a whole can make progress. - - There are three kinds of reclamation that take place, in order of increasing - invasiveness: - - an internal reclamation, where cached resource at the resource user level - is returned to the quota - - a benign reclamation phase, whereby resources that are in use but are not - helping anything make progress are reclaimed - - a destructive reclamation, whereby resources that are helping something - make progress may be enacted so that at least one part of the system can - complete. - - Only one reclamation will be outstanding for a given quota at a given time. - On each reclamation attempt, the kinds of reclamation are tried in order of - increasing invasiveness, stopping at the first one that succeeds. Thus, on a - given reclamation attempt, if internal and benign reclamation both fail, it - will wind up doing a destructive reclamation. However, the next reclamation - attempt may then be able to get what it needs via internal or benign - reclamation, due to resources that may have been freed up by the destructive - reclamation in the previous attempt. - - Future work will be to expose the current resource pressure so that back - pressure can be applied to avoid reclamation phases starting. - - Resource users own references to resource quotas, and resource quotas - maintain lists of users (which users arrange to leave before they are - destroyed) */ - -extern grpc_core::TraceFlag grpc_resource_quota_trace; - -// TODO(juanlishen): This is a hack. We need to do real accounting instead of -// hard coding. -constexpr size_t GRPC_RESOURCE_QUOTA_CALL_SIZE = 15 * 1024; -constexpr size_t GRPC_RESOURCE_QUOTA_CHANNEL_SIZE = 50 * 1024; -constexpr size_t GRPC_SLICE_ALLOCATOR_MIN_ALLOCATE_SIZE = 256; -constexpr size_t GRPC_SLICE_ALLOCATOR_MAX_ALLOCATE_SIZE = 4 * 1024 * 1024; - -grpc_resource_quota* grpc_resource_quota_ref_internal( - grpc_resource_quota* resource_quota); -void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota); -grpc_resource_quota* grpc_resource_quota_from_channel_args( - const grpc_channel_args* channel_args, bool create = true); - -/* Return a number indicating current memory pressure: - 0.0 ==> no memory usage - 1.0 ==> maximum memory usage */ -double grpc_resource_quota_get_memory_pressure( - grpc_resource_quota* resource_quota); - -size_t grpc_resource_quota_peek_size(grpc_resource_quota* resource_quota); - -typedef struct grpc_resource_user grpc_resource_user; - -grpc_resource_user* grpc_resource_user_create( - grpc_resource_quota* resource_quota, absl::string_view name); - -/* Returns a borrowed reference to the underlying resource quota for this - resource user. */ -grpc_resource_quota* grpc_resource_user_quota( - grpc_resource_user* resource_user); - -void grpc_resource_user_ref(grpc_resource_user* resource_user); -void grpc_resource_user_unref(grpc_resource_user* resource_user); -void grpc_resource_user_shutdown(grpc_resource_user* resource_user); - -/* Attempts to get quota from the resource_user to create 'thread_count' number - * of threads. Returns true if successful (i.e the caller is now free to create - * 'thread_count' number of threads) or false if quota is not available */ -bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, - int thread_count); -/* Releases 'thread_count' worth of quota back to the resource user. The quota - * should have been previously obtained successfully by calling - * grpc_resource_user_allocate_threads(). - * - * Note: There need not be an exact one-to-one correspondence between - * grpc_resource_user_allocate_threads() and grpc_resource_user_free_threads() - * calls. The only requirement is that the number of threads allocated should - * all be eventually released */ -void grpc_resource_user_free_threads(grpc_resource_user* resource_user, - int thread_count); - -/* Allocates from the resource user 'size' worth of memory if this won't exceed - * the resource quota's total size. Returns whether the allocation is done - * successfully. If allocated successfully, the memory should be freed by the - * caller eventually. */ -bool grpc_resource_user_safe_alloc(grpc_resource_user* resource_user, - size_t size); -/* Allocates from the resource user 'size' worth of memory. - * If optional_on_done is NULL, then allocate immediately. This may push the - * quota over-limit, at which point reclamation will kick in. The caller is - * always responsible to free the memory eventually. - * Returns true if the allocation was successful. Otherwise, if optional_on_done - * is non-NULL, it will be scheduled without error when the allocation has been - * granted by the quota, and the caller is responsible to free the memory - * eventually. Or it may be scheduled with an error, in which case the caller - * fails to allocate the memory and shouldn't free the memory. - */ -bool grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, - grpc_closure* optional_on_done) - GRPC_MUST_USE_RESULT; -/* Release memory back to the quota */ -void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size); -/* Post a memory reclaimer to the resource user. Only one benign and one - destructive reclaimer can be posted at once. When executed, the reclaimer - MUST call grpc_resource_user_finish_reclamation before it completes, to - return control to the resource quota. */ -void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user, - bool destructive, grpc_closure* closure); -/* Finish a reclamation step */ -void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user); - -/* Helper to allocate slices from a resource user */ -typedef struct grpc_slice_allocator { - /* Closure for when a resource user allocation completes */ - grpc_closure on_allocated; - /* Closure to call when slices have been allocated */ - grpc_closure on_done; - /* Length of slices to allocate on the current request */ - size_t length; - /* Number of slices to allocate on the current request */ - size_t count; - /* Minimum size to allocate under memory pressure. */ - size_t min_length; - /* Maximum size that can be allocated. */ - size_t max_length; - /* Destination for slices to allocate on the current request */ - grpc_slice_buffer* dest; - /* Parent resource user */ - grpc_resource_user* resource_user; -} grpc_slice_allocator; - -/// Constructs a slice allocator using configuration from \a args. -/// -/// Minimum and maximum limits for memory allocation size can be defined in -/// \a args, and used to configure an allocator. See -/// \a grpc_slice_allocator_allocate for details on how those values are used. -/// -/// Caller is responsible for calling \a grpc_slice_allocator_destroy. -grpc_slice_allocator* grpc_slice_allocator_create( - grpc_resource_quota* resource_quota, absl::string_view name, - const grpc_channel_args* args = nullptr); - -/* Cleans up after a slice_allocator. */ -void grpc_slice_allocator_destroy(grpc_slice_allocator* slice_allocator); - -enum class grpc_slice_allocator_intent { - kDefault, // Default intent allocates exactly the memory required. - kReadBuffer // ReadBuffer intent may return a smaller slice than requested if - // memory pressure is high. -}; - -/** Allocate \a count slices of length \a length into \a dest. Only one request - can be outstanding at a time. When an allocation is completed, calls \a cb - with arg \a p. Returns whether the slice was allocated inline in the - function. If true, the \a cb will not be called. The \a intent argument - allows allocation of smaller slices if memory pressure is high; the size is - implementation-dependent. */ -bool grpc_slice_allocator_allocate(grpc_slice_allocator* slice_allocator, - size_t length, size_t count, - grpc_slice_allocator_intent intent, - grpc_slice_buffer* dest, - grpc_iomgr_cb_func cb, - void* p) GRPC_MUST_USE_RESULT; - -/* Allows creation of slice_allocators (thus resource_users) without calling - * code having to understand resource_user concepts. */ -typedef struct grpc_slice_allocator_factory { - /* Parent resource quota */ - grpc_resource_quota* resource_quota; -} grpc_slice_allocator_factory; - -/* Constructs a slice allocator factory. Takes ownership of a ref on - * \a resource_quota from the caller. Caller is responsible for calling \a - * grpc_slice_allocator_factory_destroy. */ -grpc_slice_allocator_factory* grpc_slice_allocator_factory_create( - grpc_resource_quota* resource_quota); - -/* Cleans up after a slice_allocator. */ -void grpc_slice_allocator_factory_destroy( - grpc_slice_allocator_factory* slice_allocator_factory); - -/** A factory method to create and initialize a slice_allocator using the - factory's resource quota. \a name is the resulting resource_user name. \a args - are used to configure the \a slice_allocator */ -grpc_slice_allocator* grpc_slice_allocator_factory_create_slice_allocator( - grpc_slice_allocator_factory* slice_allocator_factory, - absl::string_view name, grpc_channel_args* args = nullptr); - -#endif /* GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H */ diff --git a/src/core/lib/iomgr/tcp_client.cc b/src/core/lib/iomgr/tcp_client.cc index 02b7e4b4c64..3441a63c829 100644 --- a/src/core/lib/iomgr/tcp_client.cc +++ b/src/core/lib/iomgr/tcp_client.cc @@ -23,14 +23,12 @@ grpc_tcp_client_vtable* grpc_tcp_client_impl; void grpc_tcp_client_connect(grpc_closure* on_connect, grpc_endpoint** endpoint, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, grpc_millis deadline) { - grpc_tcp_client_impl->connect(on_connect, endpoint, slice_allocator, - interested_parties, channel_args, addr, - deadline); + grpc_tcp_client_impl->connect(on_connect, endpoint, interested_parties, + channel_args, addr, deadline); } void grpc_set_tcp_client_impl(grpc_tcp_client_vtable* impl) { diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h index 995f81791c6..3e785182ea4 100644 --- a/src/core/lib/iomgr/tcp_client.h +++ b/src/core/lib/iomgr/tcp_client.h @@ -27,11 +27,10 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/resolve_address.h" -#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/resource_quota/memory_quota.h" typedef struct grpc_tcp_client_vtable { void (*connect)(grpc_closure* on_connect, grpc_endpoint** endpoint, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, grpc_millis deadline); @@ -43,7 +42,6 @@ typedef struct grpc_tcp_client_vtable { interested_parties points to a set of pollsets that would be interested in this connection being established (in order to continue their work) */ void grpc_tcp_client_connect(grpc_closure* on_connect, grpc_endpoint** endpoint, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index 5292e231138..7d3f5d63393 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -64,16 +64,12 @@ struct CFStreamConnect { grpc_endpoint** endpoint; int refs; std::string addr_name; - grpc_slice_allocator* slice_allocator; }; static void CFStreamConnectCleanup(CFStreamConnect* connect) { CFSTREAM_HANDLE_UNREF(connect->stream_handle, "async connect clean up"); CFRelease(connect->read_stream); CFRelease(connect->write_stream); - if (connect->slice_allocator != nullptr) { - grpc_slice_allocator_destroy(connect->slice_allocator); - } gpr_mu_destroy(&connect->mu); delete connect; } @@ -132,9 +128,7 @@ static void OnOpen(void* arg, grpc_error_handle error) { if (error == GRPC_ERROR_NONE) { *endpoint = grpc_cfstream_endpoint_create( connect->read_stream, connect->write_stream, - connect->addr_name.c_str(), connect->slice_allocator, - connect->stream_handle); - connect->slice_allocator = nullptr; + connect->addr_name.c_str(), connect->stream_handle); } } else { (void)GRPC_ERROR_REF(error); @@ -156,7 +150,6 @@ static void ParseResolvedAddress(const grpc_resolved_address* addr, } static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* resolved_addr, @@ -173,7 +166,6 @@ static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep, gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %p, %s: asynchronously connecting", connect, connect->addr_name.c_str()); } - connect->slice_allocator = slice_allocator; CFReadStreamRef read_stream; CFWriteStreamRef write_stream; diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc index 54aa13edd06..57c5752f228 100644 --- a/src/core/lib/iomgr/tcp_client_custom.cc +++ b/src/core/lib/iomgr/tcp_client_custom.cc @@ -42,13 +42,9 @@ struct grpc_custom_tcp_connect { grpc_endpoint** endpoint; int refs; std::string addr_name; - grpc_slice_allocator* slice_allocator; }; static void custom_tcp_connect_cleanup(grpc_custom_tcp_connect* connect) { - if (connect->slice_allocator != nullptr) { - grpc_slice_allocator_destroy(connect->slice_allocator); - } grpc_custom_socket* socket = connect->socket; delete connect; if (socket->refs == 0) { @@ -87,9 +83,8 @@ static void custom_connect_callback_internal(grpc_custom_socket* socket, grpc_closure* closure = connect->closure; grpc_timer_cancel(&connect->alarm); if (error == GRPC_ERROR_NONE) { - *connect->endpoint = custom_tcp_endpoint_create( - socket, connect->slice_allocator, connect->addr_name.c_str()); - connect->slice_allocator = nullptr; + *connect->endpoint = + custom_tcp_endpoint_create(socket, connect->addr_name.c_str()); } done = (--connect->refs == 0); socket->refs--; @@ -114,7 +109,6 @@ static void custom_connect_callback(grpc_custom_socket* socket, } static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* resolved_addr, @@ -130,7 +124,6 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, connect->closure = closure; connect->endpoint = ep; connect->addr_name = grpc_sockaddr_to_uri(resolved_addr); - connect->slice_allocator = slice_allocator; connect->socket = socket; socket->connector = connect; socket->endpoint = nullptr; diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 82f48db23af..c14233183d6 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -62,7 +62,6 @@ struct async_connect { grpc_endpoint** ep; grpc_closure* closure; grpc_channel_args* channel_args; - grpc_slice_allocator* slice_allocator; }; static grpc_error_handle prepare_socket(const grpc_resolved_address* addr, @@ -118,9 +117,6 @@ static void tc_on_alarm(void* acp, grpc_error_handle error) { gpr_mu_unlock(&ac->mu); if (done) { gpr_mu_destroy(&ac->mu); - if (ac->slice_allocator != nullptr) { - grpc_slice_allocator_destroy(ac->slice_allocator); - } grpc_channel_args_destroy(ac->channel_args); delete ac; } @@ -128,8 +124,8 @@ static void tc_on_alarm(void* acp, grpc_error_handle error) { grpc_endpoint* grpc_tcp_client_create_from_fd( grpc_fd* fd, const grpc_channel_args* channel_args, - absl::string_view addr_str, grpc_slice_allocator* slice_allocator) { - return grpc_tcp_create(fd, channel_args, addr_str, slice_allocator); + absl::string_view addr_str) { + return grpc_tcp_create(fd, channel_args, addr_str); } static void on_writable(void* acp, grpc_error_handle error) { @@ -177,9 +173,7 @@ static void on_writable(void* acp, grpc_error_handle error) { switch (so_error) { case 0: grpc_pollset_set_del_fd(ac->interested_parties, fd); - *ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str, - ac->slice_allocator); - ac->slice_allocator = nullptr; + *ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str); fd = nullptr; break; case ENOBUFS: @@ -234,10 +228,6 @@ finish: // This is safe even outside the lock, because "done", the sentinel, is // populated *inside* the lock. gpr_mu_destroy(&ac->mu); - if (ac->slice_allocator != nullptr) { - grpc_slice_allocator_destroy(ac->slice_allocator); - ac->slice_allocator = nullptr; - } grpc_channel_args_destroy(ac->channel_args); delete ac; } @@ -280,8 +270,7 @@ grpc_error_handle grpc_tcp_client_prepare_fd( void grpc_tcp_client_create_from_prepared_fd( grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, - grpc_millis deadline, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator) { + grpc_millis deadline, grpc_endpoint** ep) { int err; do { err = connect(fd, reinterpret_cast(addr->addr), @@ -292,13 +281,12 @@ void grpc_tcp_client_create_from_prepared_fd( grpc_fd* fdobj = grpc_fd_create(fd, name.c_str(), true); if (err >= 0) { - *ep = grpc_tcp_client_create_from_fd( - fdobj, channel_args, grpc_sockaddr_to_uri(addr), slice_allocator); + *ep = grpc_tcp_client_create_from_fd(fdobj, channel_args, + grpc_sockaddr_to_uri(addr)); grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, GRPC_ERROR_NONE); return; } if (errno != EWOULDBLOCK && errno != EINPROGRESS) { - grpc_slice_allocator_destroy(slice_allocator); grpc_error_handle error = GRPC_OS_ERROR(errno, "connect"); error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, grpc_sockaddr_to_uri(addr)); @@ -317,7 +305,6 @@ void grpc_tcp_client_create_from_prepared_fd( ac->addr_str = grpc_sockaddr_to_uri(addr); gpr_mu_init(&ac->mu); ac->refs = 2; - ac->slice_allocator = slice_allocator; GRPC_CLOSURE_INIT(&ac->write_closure, on_writable, ac, grpc_schedule_on_exec_ctx); ac->channel_args = grpc_channel_args_copy(channel_args); @@ -335,7 +322,6 @@ void grpc_tcp_client_create_from_prepared_fd( } static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, @@ -346,13 +332,12 @@ static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, *ep = nullptr; if ((error = grpc_tcp_client_prepare_fd(channel_args, addr, &mapped_addr, &fd)) != GRPC_ERROR_NONE) { - grpc_slice_allocator_destroy(slice_allocator); grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, error); return; } grpc_tcp_client_create_from_prepared_fd(interested_parties, closure, fd, channel_args, &mapped_addr, deadline, - ep, slice_allocator); + ep); } grpc_tcp_client_vtable grpc_posix_tcp_client_vtable = {tcp_connect}; diff --git a/src/core/lib/iomgr/tcp_client_posix.h b/src/core/lib/iomgr/tcp_client_posix.h index b2d00cc1ee7..101e5cb6ba2 100644 --- a/src/core/lib/iomgr/tcp_client_posix.h +++ b/src/core/lib/iomgr/tcp_client_posix.h @@ -35,7 +35,7 @@ */ grpc_endpoint* grpc_tcp_client_create_from_fd( grpc_fd* fd, const grpc_channel_args* channel_args, - absl::string_view addr_str, grpc_slice_allocator* slice_allocator); + absl::string_view addr_str); /* Return a configured, unbound, unconnected TCP client fd. @@ -64,7 +64,6 @@ grpc_error_handle grpc_tcp_client_prepare_fd( void grpc_tcp_client_create_from_prepared_fd( grpc_pollset_set* interested_parties, grpc_closure* closure, const int fd, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, - grpc_millis deadline, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator); + grpc_millis deadline, grpc_endpoint** ep); #endif /* GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 6297118e158..223688b6de7 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -51,7 +51,6 @@ struct async_connect { grpc_closure on_connect; grpc_endpoint** endpoint; grpc_channel_args* channel_args; - grpc_slice_allocator* slice_allocator; }; static void async_connect_unlock_and_cleanup(async_connect* ac, @@ -61,9 +60,6 @@ static void async_connect_unlock_and_cleanup(async_connect* ac, if (done) { grpc_channel_args_destroy(ac->channel_args); gpr_mu_destroy(&ac->mu); - if (ac->slice_allocator != nullptr) { - grpc_slice_allocator_destroy(ac->slice_allocator); - } delete ac; } if (socket != NULL) grpc_winsocket_destroy(socket); @@ -109,9 +105,7 @@ static void on_connect(void* acp, grpc_error_handle error) { error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx"); closesocket(socket->socket); } else { - *ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name, - ac->slice_allocator); - ac->slice_allocator = nullptr; + *ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name); socket = nullptr; } } else { @@ -128,7 +122,6 @@ static void on_connect(void* acp, grpc_error_handle error) { /* Tries to issue one async connection, then schedules both an IOCP notification request for the connection, and one timeout alert. */ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, @@ -208,7 +201,6 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, ac->refs = 2; ac->addr_name = grpc_sockaddr_to_uri(addr); ac->endpoint = endpoint; - ac->slice_allocator = slice_allocator; ac->channel_args = grpc_channel_args_copy(channel_args); GRPC_CLOSURE_INIT(&ac->on_connect, on_connect, ac, grpc_schedule_on_exec_ctx); @@ -227,7 +219,6 @@ failure: "Failed to connect", &error, 1), GRPC_ERROR_STR_TARGET_ADDRESS, target_uri); GRPC_ERROR_UNREF(error); - grpc_slice_allocator_destroy(slice_allocator); if (socket != NULL) { grpc_winsocket_destroy(socket); } else if (sock != INVALID_SOCKET) { diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index a74bc2881f5..732b03acaf5 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -32,7 +32,6 @@ #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/iomgr_custom.h" #include "src/core/lib/iomgr/port.h" -#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/slice/slice_internal.h" @@ -63,8 +62,6 @@ struct custom_tcp_endpoint { grpc_slice_buffer* read_slices = nullptr; grpc_slice_buffer* write_slices = nullptr; - grpc_slice_allocator* slice_allocator; - bool shutting_down; std::string peer_string; @@ -73,7 +70,6 @@ struct custom_tcp_endpoint { static void tcp_free(grpc_custom_socket* s) { custom_tcp_endpoint* tcp = reinterpret_cast(s->endpoint); - grpc_slice_allocator_destroy(tcp->slice_allocator); delete tcp; s->refs--; if (s->refs == 0) { @@ -167,31 +163,6 @@ static void custom_read_callback(grpc_custom_socket* socket, size_t nread, call_read_cb(tcp, error); } -static void tcp_read_allocation_done(void* tcpp, grpc_error_handle error) { - custom_tcp_endpoint* tcp = static_cast(tcpp); - if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp->socket, - grpc_error_std_string(error).c_str()); - } - if (error == GRPC_ERROR_NONE) { - /* Before calling read, we allocate a buffer with exactly one slice - * to tcp->read_slices and wait for the callback indicating that the - * allocation was successful. So slices[0] should always exist here */ - char* buffer = reinterpret_cast( - GRPC_SLICE_START_PTR(tcp->read_slices->slices[0])); - size_t len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]); - grpc_custom_socket_vtable->read(tcp->socket, buffer, len, - custom_read_callback); - } else { - grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices); - call_read_cb(tcp, GRPC_ERROR_REF(error)); - } - if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "Initiating read on %p: error=%s", tcp->socket, - grpc_error_std_string(error).c_str()); - } -} - static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, grpc_closure* cb, bool /*urgent*/) { custom_tcp_endpoint* tcp = reinterpret_cast(ep); @@ -201,12 +172,16 @@ static void endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices, tcp->read_slices = read_slices; grpc_slice_buffer_reset_and_unref_internal(read_slices); TCP_REF(tcp, "read"); - if (grpc_slice_allocator_allocate( - tcp->slice_allocator, GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1, - grpc_slice_allocator_intent::kReadBuffer, tcp->read_slices, - tcp_read_allocation_done, tcp)) { - tcp_read_allocation_done(tcp, GRPC_ERROR_NONE); + if (tcp->read_slices->length < GRPC_TCP_DEFAULT_READ_SLICE_SIZE) { + grpc_slice_buffer_add_indexed( + tcp->read_slices, GRPC_SLICE_MALLOC(GRPC_TCP_DEFAULT_READ_SLICE_SIZE)); } + /* slices[0] should always exist here since we just added it if it did not */ + char* buffer = reinterpret_cast( + GRPC_SLICE_START_PTR(tcp->read_slices->slices[0])); + size_t len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]); + grpc_custom_socket_vtable->read(tcp->socket, buffer, len, + custom_read_callback); } static void custom_write_callback(grpc_custom_socket* socket, @@ -346,7 +321,6 @@ static grpc_endpoint_vtable vtable = {endpoint_read, endpoint_can_track_err}; grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, - grpc_slice_allocator* slice_allocator, const char* peer_string) { custom_tcp_endpoint* tcp = new custom_tcp_endpoint; grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; @@ -372,6 +346,5 @@ grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, tcp->local_address = grpc_sockaddr_to_uri(&resolved_local_addr); } tcp->shutting_down = false; - tcp->slice_allocator = slice_allocator; return &tcp->base; } diff --git a/src/core/lib/iomgr/tcp_custom.h b/src/core/lib/iomgr/tcp_custom.h index f0778e04967..6385d044a5e 100644 --- a/src/core/lib/iomgr/tcp_custom.h +++ b/src/core/lib/iomgr/tcp_custom.h @@ -80,7 +80,6 @@ void grpc_custom_close_server_callback(grpc_tcp_listener* listener); /// Takes ownership of \a slice_allocator. grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket, - grpc_slice_allocator* slice_allocator, const char* peer_string); #endif /* GRPC_CORE_LIB_IOMGR_TCP_CUSTOM_H */ diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index fd77bfab4fc..3c943b0e53d 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -18,6 +18,8 @@ #include +#include + #include "src/core/lib/iomgr/port.h" #ifdef GRPC_POSIX_SOCKET_TCP @@ -54,10 +56,11 @@ #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/executor.h" -#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/iomgr/tcp_posix.h" #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/resource_quota/api.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" @@ -393,7 +396,8 @@ struct grpc_tcp { std::string peer_string; std::string local_address; - grpc_slice_allocator* slice_allocator; + grpc_core::MemoryOwner memory_owner; + grpc_core::MemoryAllocator::Reservation self_reservation; grpc_core::TracedBuffer* tb_head; /* List of traced buffers */ gpr_mu tb_mu; /* Lock for access to list of traced buffers */ @@ -608,7 +612,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_fd_orphan(tcp->em_fd, tcp->release_fd_cb, tcp->release_fd, "tcp_unref_orphan"); grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); - grpc_slice_allocator_destroy(tcp->slice_allocator); /* The lock is not really necessary here, since all refs have been released */ gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::Shutdown( @@ -701,6 +704,8 @@ static void tcp_do_read(grpc_tcp* tcp) { iov[i].iov_len = GRPC_SLICE_LENGTH(tcp->incoming_buffer->slices[i]); } + GPR_ASSERT(tcp->incoming_buffer->length != 0); + do { /* Assume there is something on the queue. If we receive TCP_INQ from * kernel, we will update this value, otherwise, we have to assume there is @@ -787,7 +792,6 @@ static void tcp_do_read(grpc_tcp* tcp) { total_read_bytes += read_bytes; if (tcp->inq == 0 || total_read_bytes == tcp->incoming_buffer->length) { - /* We have filled incoming_buffer, and we cannot read any more. */ break; } @@ -827,36 +831,25 @@ static void tcp_do_read(grpc_tcp* tcp) { TCP_UNREF(tcp, "read"); } -static void tcp_read_allocation_done(void* tcpp, grpc_error_handle error) { - grpc_tcp* tcp = static_cast(tcpp); - if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "TCP:%p read_allocation_done: %s", tcp, - grpc_error_std_string(error).c_str()); - } - if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) { - grpc_slice_buffer_reset_and_unref_internal(tcp->incoming_buffer); - grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); - call_read_cb(tcp, GRPC_ERROR_REF(error)); - TCP_UNREF(tcp, "read"); - } else { - tcp_do_read(tcp); - } -} - static void tcp_continue_read(grpc_tcp* tcp) { - /* Wait for allocation only when there is no buffer left. */ if (tcp->incoming_buffer->length == 0 && tcp->incoming_buffer->count < MAX_READ_IOVEC) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "TCP:%p alloc_slices", tcp); - } - if (GPR_UNLIKELY(!grpc_slice_allocator_allocate( - tcp->slice_allocator, tcp->target_length, 1, - grpc_slice_allocator_intent::kReadBuffer, tcp->incoming_buffer, - tcp_read_allocation_done, tcp))) { - // Wait for allocation. - return; + gpr_log(GPR_INFO, + "TCP:%p alloc_slices; min_chunk=%d max_chunk=%d target=%lf " + "buf_len=%" PRIdPTR, + tcp, tcp->min_read_chunk_size, tcp->max_read_chunk_size, + tcp->target_length, tcp->incoming_buffer->length); } + int target_length = static_cast(tcp->target_length); + int extra_wanted = + target_length - static_cast(tcp->incoming_buffer->length); + grpc_slice_buffer_add_indexed( + tcp->incoming_buffer, + tcp->memory_owner.MakeSlice(grpc_core::MemoryRequest( + tcp->min_read_chunk_size, + grpc_core::Clamp(extra_wanted, tcp->min_read_chunk_size, + tcp->max_read_chunk_size)))); } if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { gpr_log(GPR_INFO, "TCP:%p do_read", tcp); @@ -1669,8 +1662,7 @@ static const grpc_endpoint_vtable vtable = {tcp_read, grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, const grpc_channel_args* channel_args, - absl::string_view peer_string, - grpc_slice_allocator* slice_allocator) { + absl::string_view peer_string) { static constexpr bool kZerocpTxEnabledDefault = false; int tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE; int tcp_max_read_chunk_size = 4 * 1024 * 1024; @@ -1729,7 +1721,10 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->base.vtable = &vtable; tcp->peer_string = std::string(peer_string); tcp->fd = grpc_fd_wrapped_fd(em_fd); - tcp->slice_allocator = slice_allocator; + tcp->memory_owner = grpc_core::ResourceQuotaFromChannelArgs(channel_args) + ->memory_quota() + ->CreateMemoryOwner(peer_string); + tcp->self_reservation = tcp->memory_owner.MakeReservation(sizeof(grpc_tcp)); grpc_resolved_address resolved_local_addr; memset(&resolved_local_addr, 0, sizeof(resolved_local_addr)); resolved_local_addr.len = sizeof(resolved_local_addr.addr); diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index 7d1433d5aaf..d657539bc04 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -36,15 +36,13 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/port.h" -#include "src/core/lib/iomgr/resource_quota.h" extern grpc_core::TraceFlag grpc_tcp_trace; /// Create a tcp endpoint given a file desciptor and a read slice size. /// Takes ownership of \a fd. Takes ownership of the \a slice_allocator. grpc_endpoint* grpc_tcp_create(grpc_fd* fd, const grpc_channel_args* args, - absl::string_view peer_string, - grpc_slice_allocator* slice_allocator); + absl::string_view peer_string); /// Return the tcp endpoint's fd, or -1 if this is not available. Does not /// release the fd. Requires: \a ep must be a tcp endpoint. diff --git a/src/core/lib/iomgr/tcp_server.cc b/src/core/lib/iomgr/tcp_server.cc index 70be5876e7b..8d6fefbbb20 100644 --- a/src/core/lib/iomgr/tcp_server.cc +++ b/src/core/lib/iomgr/tcp_server.cc @@ -22,12 +22,10 @@ grpc_tcp_server_vtable* grpc_tcp_server_impl; -grpc_error_handle grpc_tcp_server_create( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server) { - return grpc_tcp_server_impl->create(shutdown_complete, args, - slice_allocator_factory, server); +grpc_error_handle grpc_tcp_server_create(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server) { + return grpc_tcp_server_impl->create(shutdown_complete, args, server); } void grpc_tcp_server_start(grpc_tcp_server* server, diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 9a65b6ed99f..9c88428021f 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -63,10 +63,9 @@ class TcpServerFdHandler { } // namespace grpc_core typedef struct grpc_tcp_server_vtable { - grpc_error_handle (*create)( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server); + grpc_error_handle (*create)(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server); void (*start)(grpc_tcp_server* server, const std::vector* pollsets, grpc_tcp_server_cb on_accept_cb, void* cb_arg); @@ -87,10 +86,9 @@ typedef struct grpc_tcp_server_vtable { If shutdown_complete is not NULL, it will be used by grpc_tcp_server_unref() when the ref count reaches zero. Takes ownership of the slice_allocator_factory. */ -grpc_error_handle grpc_tcp_server_create( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server); +grpc_error_handle grpc_tcp_server_create(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server); /* Start listening to bound ports */ void grpc_tcp_server_start(grpc_tcp_server* server, diff --git a/src/core/lib/iomgr/tcp_server_custom.cc b/src/core/lib/iomgr/tcp_server_custom.cc index a75b2cd1cc4..1cd13eaea77 100644 --- a/src/core/lib/iomgr/tcp_server_custom.cc +++ b/src/core/lib/iomgr/tcp_server_custom.cc @@ -76,16 +76,12 @@ struct grpc_tcp_server { bool shutdown; bool so_reuseport; - - grpc_slice_allocator_factory* slice_allocator_factory; }; -static grpc_error_handle tcp_server_create( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server) { - grpc_tcp_server* s = - static_cast(gpr_malloc(sizeof(grpc_tcp_server))); +static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server) { + grpc_tcp_server* s = new grpc_tcp_server(); s->so_reuseport = grpc_channel_args_find_bool(args, GRPC_ARG_ALLOW_REUSEPORT, true); gpr_ref_init(&s->refs, 1); @@ -98,7 +94,6 @@ static grpc_error_handle tcp_server_create( s->shutdown_starting.tail = nullptr; s->shutdown_complete = shutdown_complete; s->shutdown = false; - s->slice_allocator_factory = slice_allocator_factory; *server = s; return GRPC_ERROR_NONE; } @@ -128,7 +123,6 @@ static void finish_shutdown(grpc_tcp_server* s) { sp->next = nullptr; gpr_free(sp); } - grpc_slice_allocator_factory_destroy(s->slice_allocator_factory); gpr_free(s); } @@ -219,11 +213,7 @@ static void finish_accept(grpc_tcp_listener* sp, grpc_custom_socket* socket) { gpr_log(GPR_INFO, "SERVER_CONNECT: %p accepted connection: %s", sp->server, peer_name_string.c_str()); } - ep = custom_tcp_endpoint_create( - socket, - grpc_slice_allocator_factory_create_slice_allocator( - sp->server->slice_allocator_factory, peer_name_string), - peer_name_string.c_str()); + ep = custom_tcp_endpoint_create(socket, peer_name_string.c_str()); acceptor->from_server = sp->server; acceptor->port_index = sp->port_index; acceptor->fd_index = 0; diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 92ad889df16..580a1f2cff7 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -59,12 +59,12 @@ #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/tcp_server_utils_posix.h" #include "src/core/lib/iomgr/unix_sockets_posix.h" +#include "src/core/lib/resource_quota/api.h" -static grpc_error_handle tcp_server_create( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server) { - grpc_tcp_server* s = grpc_core::Zalloc(); +static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server) { + grpc_tcp_server* s = new grpc_tcp_server; s->so_reuseport = grpc_is_socket_reuse_port_supported(); s->expand_wildcard_addrs = false; for (size_t i = 0; i < (args == nullptr ? 0 : args->num_args); i++) { @@ -74,7 +74,6 @@ static grpc_error_handle tcp_server_create( (args->args[i].value.integer != 0); } else { gpr_free(s); - grpc_slice_allocator_factory_destroy(slice_allocator_factory); return GRPC_ERROR_CREATE_FROM_STATIC_STRING(GRPC_ARG_ALLOW_REUSEPORT " must be an integer"); } @@ -83,7 +82,6 @@ static grpc_error_handle tcp_server_create( s->expand_wildcard_addrs = (args->args[i].value.integer != 0); } else { gpr_free(s); - grpc_slice_allocator_factory_destroy(slice_allocator_factory); return GRPC_ERROR_CREATE_FROM_STATIC_STRING( GRPC_ARG_EXPAND_WILDCARD_ADDRS " must be an integer"); } @@ -104,7 +102,8 @@ static grpc_error_handle tcp_server_create( s->nports = 0; s->channel_args = grpc_channel_args_copy(args); s->fd_handler = nullptr; - s->slice_allocator_factory = slice_allocator_factory; + s->memory_quota = + grpc_core::ResourceQuotaFromChannelArgs(args)->memory_quota(); gpr_atm_no_barrier_store(&s->next_pollset_to_assign, 0); *server = s; return GRPC_ERROR_NONE; @@ -124,10 +123,9 @@ static void finish_shutdown(grpc_tcp_server* s) { s->head = sp->next; gpr_free(sp); } - grpc_slice_allocator_factory_destroy(s->slice_allocator_factory); grpc_channel_args_destroy(s->channel_args); delete s->fd_handler; - gpr_free(s); + delete s; } static void destroyed_port(void* server, grpc_error_handle /*error*/) { @@ -222,6 +220,12 @@ static void on_read(void* arg, grpc_error_handle err) { } } + if (sp->server->memory_quota->IsMemoryPressureHigh()) { + gpr_log(GPR_INFO, "Drop incoming connection: high memory pressure"); + close(fd); + continue; + } + /* For UNIX sockets, the accept call might not fill up the member sun_path * of sockaddr_un, so explicitly call getsockname to get it. */ if (grpc_is_unix_socket(&addr)) { @@ -268,11 +272,7 @@ static void on_read(void* arg, grpc_error_handle err) { acceptor->external_connection = false; sp->server->on_accept_cb( sp->server->on_accept_cb_arg, - grpc_tcp_create(fdobj, sp->server->channel_args, addr_str, - grpc_slice_allocator_factory_create_slice_allocator( - sp->server->slice_allocator_factory, - absl::StrCat("tcp_server_posix:", addr_str), - sp->server->channel_args)), + grpc_tcp_create(fdobj, sp->server->channel_args, addr_str), read_notifier_pollset, acceptor); } @@ -615,13 +615,9 @@ class ExternalConnectionHandler : public grpc_core::TcpServerFdHandler { acceptor->external_connection = true; acceptor->listener_fd = listener_fd; acceptor->pending_data = buf; - s_->on_accept_cb( - s_->on_accept_cb_arg, - grpc_tcp_create( - fdobj, s_->channel_args, addr_str, - grpc_slice_allocator_factory_create_slice_allocator( - s_->slice_allocator_factory, addr_str, s_->channel_args)), - read_notifier_pollset, acceptor); + s_->on_accept_cb(s_->on_accept_cb_arg, + grpc_tcp_create(fdobj, s_->channel_args, addr_str), + read_notifier_pollset, acceptor); } private: diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h index 6cce4c12574..79527c24613 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix.h +++ b/src/core/lib/iomgr/tcp_server_utils_posix.h @@ -25,6 +25,7 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/resource_quota/memory_quota.h" /* one listening port */ typedef struct grpc_tcp_listener { @@ -52,51 +53,51 @@ typedef struct grpc_tcp_listener { struct grpc_tcp_server { gpr_refcount refs; /* Called whenever accept() succeeds on a server port. */ - grpc_tcp_server_cb on_accept_cb; - void* on_accept_cb_arg; + grpc_tcp_server_cb on_accept_cb = nullptr; + void* on_accept_cb_arg = nullptr; gpr_mu mu; /* active port count: how many ports are actually still listening */ - size_t active_ports; + size_t active_ports = 0; /* destroyed port count: how many ports are completely destroyed */ - size_t destroyed_ports; + size_t destroyed_ports = 0; /* is this server shutting down? */ - bool shutdown; + bool shutdown = false; /* have listeners been shutdown? */ - bool shutdown_listeners; + bool shutdown_listeners = false; /* use SO_REUSEPORT */ - bool so_reuseport; + bool so_reuseport = false; /* expand wildcard addresses to a list of all local addresses */ - bool expand_wildcard_addrs; + bool expand_wildcard_addrs = false; /* linked list of server ports */ - grpc_tcp_listener* head; - grpc_tcp_listener* tail; - unsigned nports; + grpc_tcp_listener* head = nullptr; + grpc_tcp_listener* tail = nullptr; + unsigned nports = 0; /* List of closures passed to shutdown_starting_add(). */ - grpc_closure_list shutdown_starting; + grpc_closure_list shutdown_starting{nullptr, nullptr}; /* shutdown callback */ - grpc_closure* shutdown_complete; + grpc_closure* shutdown_complete = nullptr; /* all pollsets interested in new connections. The object pointed at is not * owned by this struct */ - const std::vector* pollsets; + const std::vector* pollsets = nullptr; /* next pollset to assign a channel to */ - gpr_atm next_pollset_to_assign; + gpr_atm next_pollset_to_assign = 0; /* channel args for this server */ - grpc_channel_args* channel_args; + grpc_channel_args* channel_args = nullptr; /* a handler for external connections, owned */ - grpc_core::TcpServerFdHandler* fd_handler; + grpc_core::TcpServerFdHandler* fd_handler = nullptr; /* used to create slice allocators for endpoints, owned */ - grpc_slice_allocator_factory* slice_allocator_factory; + grpc_core::MemoryQuotaRefPtr memory_quota; }; /* If successful, add a listener to \a s for \a addr, set \a dsmode for the diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 3ae3d56ba34..a01e4edc037 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -96,15 +96,13 @@ struct grpc_tcp_server { grpc_closure* shutdown_complete; grpc_channel_args* channel_args; - grpc_slice_allocator_factory* slice_allocator_factory; }; /* Public function. Allocates the proper data structures to hold a grpc_tcp_server. */ -static grpc_error_handle tcp_server_create( - grpc_closure* shutdown_complete, const grpc_channel_args* args, - grpc_slice_allocator_factory* slice_allocator_factory, - grpc_tcp_server** server) { +static grpc_error_handle tcp_server_create(grpc_closure* shutdown_complete, + const grpc_channel_args* args, + grpc_tcp_server** server) { grpc_tcp_server* s = (grpc_tcp_server*)gpr_malloc(sizeof(grpc_tcp_server)); s->channel_args = grpc_channel_args_copy(args); gpr_ref_init(&s->refs, 1); @@ -117,7 +115,6 @@ static grpc_error_handle tcp_server_create( s->shutdown_starting.head = NULL; s->shutdown_starting.tail = NULL; s->shutdown_complete = shutdown_complete; - s->slice_allocator_factory = slice_allocator_factory; *server = s; return GRPC_ERROR_NONE; } @@ -168,7 +165,6 @@ static void tcp_server_shutdown_starting_add(grpc_tcp_server* s, static void tcp_server_destroy(grpc_tcp_server* s) { grpc_tcp_listener* sp; gpr_mu_lock(&s->mu); - grpc_slice_allocator_factory_destroy(s->slice_allocator_factory); /* First, shutdown all fd's. This will queue abortion calls for all of the pending accepts due to the normal operation mechanism. */ if (s->active_ports == 0) { @@ -358,11 +354,8 @@ static void on_accept(void* arg, grpc_error_handle error) { gpr_free(utf8_message); } std::string fd_name = absl::StrCat("tcp_server:", peer_name_string); - ep = grpc_tcp_create( - grpc_winsocket_create(sock, fd_name.c_str()), - sp->server->channel_args, peer_name_string, - grpc_slice_allocator_factory_create_slice_allocator( - sp->server->slice_allocator_factory, peer_name_string)); + ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name.c_str()), + sp->server->channel_args, peer_name_string); } else { closesocket(sock); } diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 96146641772..1f26eac43e6 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -116,8 +116,6 @@ typedef struct grpc_tcp { grpc_slice_buffer* write_slices; grpc_slice_buffer* read_slices; - grpc_slice_allocator* slice_allocator; - /* The IO Completion Port runs from another thread. We need some mechanism to protect ourselves when requesting a shutdown. */ gpr_mu mu; @@ -132,7 +130,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_winsocket_destroy(tcp->socket); gpr_mu_destroy(&tcp->mu); grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); - grpc_slice_allocator_destroy(tcp->slice_allocator); if (tcp->shutting_down) GRPC_ERROR_UNREF(tcp->shutdown_error); delete tcp; } @@ -502,8 +499,7 @@ static grpc_endpoint_vtable vtable = {win_read, grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, grpc_channel_args* channel_args, - absl::string_view peer_string, - grpc_slice_allocator* slice_allocator) { + absl::string_view peer_string) { grpc_tcp* tcp = new grpc_tcp; memset(tcp, 0, sizeof(grpc_tcp)); tcp->base.vtable = &vtable; @@ -523,7 +519,6 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, } tcp->peer_string = std::string(peer_string); grpc_slice_buffer_init(&tcp->last_read_buffer); - tcp->slice_allocator = slice_allocator; return &tcp->base; } diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h index 764101437de..9c6ad526850 100644 --- a/src/core/lib/iomgr/tcp_windows.h +++ b/src/core/lib/iomgr/tcp_windows.h @@ -42,8 +42,7 @@ */ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket, grpc_channel_args* channel_args, - absl::string_view peer_string, - grpc_slice_allocator* slice_allocator); + absl::string_view peer_string); grpc_error_handle grpc_tcp_prepare_socket(SOCKET sock); diff --git a/src/core/lib/promise/activity.cc b/src/core/lib/promise/activity.cc index 48a5cf30f80..00b11b05271 100644 --- a/src/core/lib/promise/activity.cc +++ b/src/core/lib/promise/activity.cc @@ -25,8 +25,7 @@ namespace grpc_core { /////////////////////////////////////////////////////////////////////////////// // GLOBALS -ABSL_CONST_INIT GPR_THREAD_LOCAL(Activity*) Activity::g_current_activity_ = - nullptr; +GPR_THREAD_LOCAL(Activity*) Activity::g_current_activity_{nullptr}; Waker::Unwakeable Waker::unwakeable_; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/lib/resource_quota/api.cc b/src/core/lib/resource_quota/api.cc new file mode 100644 index 00000000000..3ba4ca6e21c --- /dev/null +++ b/src/core/lib/resource_quota/api.cc @@ -0,0 +1,102 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/core/lib/resource_quota/api.h" + +#include + +#include "src/core/lib/gpr/useful.h" + +namespace grpc_core { + +ResourceQuotaRefPtr ResourceQuotaFromChannelArgs( + const grpc_channel_args* args) { + return grpc_channel_args_find_pointer(args, + GRPC_ARG_RESOURCE_QUOTA) + ->Ref(); +} + +namespace { +grpc_arg MakeArg(ResourceQuota* quota) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_RESOURCE_QUOTA), quota, + grpc_resource_quota_arg_vtable()); +} +} // namespace + +grpc_channel_args* EnsureResourceQuotaInChannelArgs( + const grpc_channel_args* args) { + if (grpc_channel_args_find(args, GRPC_ARG_RESOURCE_QUOTA) != nullptr) { + return grpc_channel_args_copy(args); + } + // If there's no existing quota, add it to the default one - shared between + // all channel args declared thusly. This prevents us from accidentally not + // sharing subchannels due to their channel args not specifying a quota. + auto new_arg = MakeArg(ResourceQuota::Default().get()); + return grpc_channel_args_copy_and_add(args, &new_arg, 1); +} + +grpc_channel_args* ChannelArgsWrappingResourceQuota( + ResourceQuotaRefPtr resource_quota) { + auto new_arg = MakeArg(resource_quota.get()); + return grpc_channel_args_copy_and_add(nullptr, &new_arg, 1); +} + +} // namespace grpc_core + +extern "C" const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable() { + static const grpc_arg_pointer_vtable vtable = { + // copy + [](void* p) -> void* { + return static_cast(p)->Ref().release(); + }, + // destroy + [](void* p) { static_cast(p)->Unref(); }, + // compare + [](void* p, void* q) { return grpc_core::QsortCompare(p, q); }}; + return &vtable; +} + +extern "C" grpc_resource_quota* grpc_resource_quota_create(const char* name) { + static std::atomic anonymous_counter{0}; + std::string quota_name = + name == nullptr + ? absl::StrCat("anonymous-quota-", anonymous_counter.fetch_add(1)) + : name; + return (new grpc_core::ResourceQuota(std::move(quota_name)))->c_ptr(); +} + +extern "C" void grpc_resource_quota_ref(grpc_resource_quota* resource_quota) { + grpc_core::ResourceQuota::FromC(resource_quota)->Ref().release(); +} + +extern "C" void grpc_resource_quota_unref(grpc_resource_quota* resource_quota) { + grpc_core::ResourceQuota::FromC(resource_quota)->Unref(); +} + +extern "C" void grpc_resource_quota_resize(grpc_resource_quota* resource_quota, + size_t new_size) { + grpc_core::ResourceQuota::FromC(resource_quota) + ->memory_quota() + ->SetSize(new_size); +} + +extern "C" void grpc_resource_quota_set_max_threads( + grpc_resource_quota* resource_quota, int new_max_threads) { + grpc_core::ResourceQuota::FromC(resource_quota) + ->thread_quota() + ->SetMax(new_max_threads); +} diff --git a/src/core/lib/resource_quota/api.h b/src/core/lib/resource_quota/api.h new file mode 100644 index 00000000000..fd6c58cd5c7 --- /dev/null +++ b/src/core/lib/resource_quota/api.h @@ -0,0 +1,52 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GRPC_CORE_LIB_RESOURCE_QUOTA_API_H +#define GRPC_CORE_LIB_RESOURCE_QUOTA_API_H + +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/resource_quota/resource_quota.h" + +typedef struct grpc_resource_quota grpc_resource_quota; + +namespace grpc_core { + +// TODO(ctiller): This is a hack. We need to do real accounting instead of +// hard coding. +constexpr size_t kResourceQuotaCallSize = 15 * 1024; +constexpr size_t kResourceQuotaChannelSize = 50 * 1024; + +// Retrieve the resource quota from the channel args. +// UB if not set. +ResourceQuotaRefPtr ResourceQuotaFromChannelArgs(const grpc_channel_args* args); + +// Take some channel args: +// If there is a resource quota set, copy args and return that. +// If there is no resource quota set, set a default, and return new +// channel args. Call grpc_channel_args_destroy on the input args. +grpc_channel_args* EnsureResourceQuotaInChannelArgs( + const grpc_channel_args* args); + +// Create channel args with just the passed in resource quota +grpc_channel_args* ChannelArgsWrappingResourceQuota(ResourceQuotaRefPtr); + +inline ResourceQuota* ResourceQuotaFromC(grpc_resource_quota* quota) { + return reinterpret_cast(quota); +} + +} // namespace grpc_core + +#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_API_H diff --git a/src/core/lib/resource_quota/memory_quota.cc b/src/core/lib/resource_quota/memory_quota.cc index c72c09e9638..e651324433c 100644 --- a/src/core/lib/resource_quota/memory_quota.cc +++ b/src/core/lib/resource_quota/memory_quota.cc @@ -19,8 +19,10 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h" #include "src/core/lib/promise/loop.h" +#include "src/core/lib/promise/map.h" #include "src/core/lib/promise/race.h" #include "src/core/lib/promise/seq.h" +#include "src/core/lib/resource_quota/trace.h" namespace grpc_core { @@ -104,8 +106,8 @@ Poll ReclaimerQueue::PollNext() { // GrpcMemoryAllocatorImpl::GrpcMemoryAllocatorImpl( - std::shared_ptr memory_quota) - : memory_quota_(memory_quota) { + std::shared_ptr memory_quota, std::string name) + : memory_quota_(memory_quota), name_(std::move(name)) { memory_quota_->Take(taken_bytes_); } @@ -157,9 +159,14 @@ absl::optional GrpcMemoryAllocatorImpl::TryReserve( // flexibility. if (scaled_size_over_min != 0) { double pressure; + size_t max_recommended_allocation_size; { MutexLock lock(&memory_quota_mu_); - pressure = memory_quota_->InstantaneousPressure(); + const auto pressure_and_max_recommended_allocation_size = + memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize(); + pressure = pressure_and_max_recommended_allocation_size.first; + max_recommended_allocation_size = + pressure_and_max_recommended_allocation_size.second; } // Reduce allocation size proportional to the pressure > 80% usage. if (pressure > 0.8) { @@ -168,6 +175,12 @@ absl::optional GrpcMemoryAllocatorImpl::TryReserve( static_cast((request.max() - request.min()) * (1.0 - pressure) / 0.2)); } + if (max_recommended_allocation_size < request.min()) { + scaled_size_over_min = 0; + } else if (request.min() + scaled_size_over_min > + max_recommended_allocation_size) { + scaled_size_over_min = max_recommended_allocation_size - request.min(); + } } // How much do we want to reserve? @@ -279,8 +292,7 @@ void GrpcMemoryAllocatorImpl::PostReclaimer(ReclamationPass pass, // void MemoryOwner::Rebind(MemoryQuota* quota) { - static_cast(allocator_.get_internal_impl_ptr()) - ->Rebind(quota->memory_quota_); + impl()->Rebind(quota->memory_quota_); } // @@ -327,10 +339,22 @@ void BasicMemoryQuota::Start() { // Race biases to the first thing that completes... so this will // choose the highest priority/least destructive thing to do that's // available. - return Race(self->reclaimers_[0].Next(), self->reclaimers_[1].Next(), - self->reclaimers_[2].Next(), self->reclaimers_[3].Next()); + auto annotate = [](const char* name) { + return [name](ReclamationFunction f) { + return std::make_tuple(name, std::move(f)); + }; + }; + return Race(Map(self->reclaimers_[0].Next(), annotate("compact")), + Map(self->reclaimers_[1].Next(), annotate("benign")), + Map(self->reclaimers_[2].Next(), annotate("idle")), + Map(self->reclaimers_[3].Next(), annotate("destructive"))); }, - [self](ReclamationFunction reclaimer) { + [self](std::tuple arg) { + auto reclaimer = std::move(std::get<1>(arg)); + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { + gpr_log(GPR_INFO, "RQ: %s perform %s reclamation", + self->name_.c_str(), std::get<0>(arg)); + } // One of the reclaimer queues gave us a way to get back memory. // Call the reclaimer with a token that contains enough to wake us // up again. @@ -386,6 +410,9 @@ void BasicMemoryQuota::FinishReclamation(uint64_t token) { if (reclamation_counter_.compare_exchange_strong(current, current + 1, std::memory_order_relaxed, std::memory_order_relaxed)) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { + gpr_log(GPR_INFO, "RQ: %s reclamation complete", name_.c_str()); + } if (reclaimer_activity_ != nullptr) reclaimer_activity_->ForceWakeup(); } } @@ -394,15 +421,33 @@ void BasicMemoryQuota::Return(size_t amount) { free_bytes_.fetch_add(amount, std::memory_order_relaxed); } -size_t BasicMemoryQuota::InstantaneousPressure() const { +std::pair +BasicMemoryQuota::InstantaneousPressureAndMaxRecommendedAllocationSize() const { double free = free_bytes_.load(); if (free < 0) free = 0; - double size = quota_size_.load(); - if (size < 1) return 1.0; + size_t quota_size = quota_size_.load(); + double size = quota_size; + if (size < 1) return std::make_pair(1.0, 1); double pressure = (size - free) / size; if (pressure < 0.0) pressure = 0.0; if (pressure > 1.0) pressure = 1.0; - return pressure; + return std::make_pair(pressure, quota_size / 16); +} + +// +// MemoryQuota +// + +MemoryAllocator MemoryQuota::CreateMemoryAllocator(absl::string_view name) { + auto impl = std::make_shared( + memory_quota_, absl::StrCat(memory_quota_->name(), "/allocator/", name)); + return MemoryAllocator(std::move(impl)); +} + +MemoryOwner MemoryQuota::CreateMemoryOwner(absl::string_view name) { + auto impl = std::make_shared( + memory_quota_, absl::StrCat(memory_quota_->name(), "/owner/", name)); + return MemoryOwner(std::move(impl)); } } // namespace grpc_core diff --git a/src/core/lib/resource_quota/memory_quota.h b/src/core/lib/resource_quota/memory_quota.h index c19c26295c5..cd133fb7acc 100644 --- a/src/core/lib/resource_quota/memory_quota.h +++ b/src/core/lib/resource_quota/memory_quota.h @@ -27,6 +27,7 @@ #include #include +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/promise/activity.h" #include "src/core/lib/promise/poll.h" @@ -77,6 +78,7 @@ static constexpr size_t kNumReclamationPasses = 4; // then that reclamation is complete and we may continue the reclamation loop. class ReclamationSweep { public: + ReclamationSweep() = default; ReclamationSweep(std::shared_ptr memory_quota, uint64_t sweep_token) : memory_quota_(std::move(memory_quota)), sweep_token_(sweep_token) {} @@ -94,6 +96,13 @@ class ReclamationSweep { // work item. bool IsSufficient() const; + // Explicit finish for users that wish to write it. + // Just destroying the object is enough, but sometimes the additional + // explicitness is warranted. + void Finish() { + [](ReclamationSweep) {}(std::move(*this)); + } + private: std::shared_ptr memory_quota_; uint64_t sweep_token_; @@ -170,6 +179,8 @@ class ReclaimerQueue { class BasicMemoryQuota final : public std::enable_shared_from_this { public: + explicit BasicMemoryQuota(std::string name) : name_(std::move(name)) {} + // Start the reclamation activity. void Start(); // Stop the reclamation activity. @@ -188,7 +199,8 @@ class BasicMemoryQuota final // Return some memory to the quota. void Return(size_t amount); // Instantaneous memory pressure approximation. - size_t InstantaneousPressure() const; + std::pair + InstantaneousPressureAndMaxRecommendedAllocationSize() const; // Cancel a reclaimer ReclamationFunction CancelReclaimer( size_t reclaimer, typename ReclaimerQueue::Index index, @@ -203,6 +215,9 @@ class BasicMemoryQuota final reclaimers_[reclaimer].Insert(std::move(allocator), std::move(fn), index); } + // The name of this quota + absl::string_view name() const { return name_; } + private: friend class ReclamationSweep; class WaitForSweepPromise; @@ -228,6 +243,8 @@ class BasicMemoryQuota final // We also increment this counter on completion of a sweep, as an indicator // that the wait has ended. std::atomic reclamation_counter_{0}; + // The name of this quota - used for debugging/tracing/etc.. + std::string name_; }; // MemoryAllocatorImpl grants the owner the ability to allocate memory from an @@ -235,7 +252,7 @@ class BasicMemoryQuota final class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl { public: explicit GrpcMemoryAllocatorImpl( - std::shared_ptr memory_quota); + std::shared_ptr memory_quota, std::string name); ~GrpcMemoryAllocatorImpl() override; // Rebind - Swaps the underlying quota for this allocator, taking care to @@ -263,6 +280,16 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl { // Shutdown the allocator. void Shutdown() override; + // Read the instantaneous memory pressure + double InstantaneousPressure() const { + MutexLock lock(&memory_quota_mu_); + return memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize() + .first; + } + + // Name of this allocator + absl::string_view name() const { return name_; } + private: // Primitive reservation function. absl::optional TryReserve(MemoryRequest request) GRPC_MUST_USE_RESULT; @@ -281,7 +308,7 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl { // pressure. std::atomic free_bytes_{0}; // Mutex guarding the backing resource quota. - Mutex memory_quota_mu_; + mutable Mutex memory_quota_mu_; // Backing resource quota. std::shared_ptr memory_quota_ ABSL_GUARDED_BY(memory_quota_mu_); @@ -296,35 +323,65 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl { memory_quota_mu_) = { ReclaimerQueue::kInvalidIndex, ReclaimerQueue::kInvalidIndex, ReclaimerQueue::kInvalidIndex, ReclaimerQueue::kInvalidIndex}; + // Name of this allocator. + std::string name_; }; // MemoryOwner is an enhanced MemoryAllocator that can also reclaim memory, and // be rebound to a different memory quota. -class MemoryOwner { +// Different modules should not share a MemoryOwner between themselves, instead +// each module that requires a MemoryOwner should create one from a resource +// quota. This is because the MemoryOwner reclaimers are tied to the +// MemoryOwner's lifetime, and are not queryable, so passing a MemoryOwner to a +// new owning module means that module cannot reason about which reclaimers are +// active, nor what they might do. +class MemoryOwner final : public MemoryAllocator { public: - explicit MemoryOwner(std::shared_ptr allocator) - : allocator_(std::move(allocator)) {} + MemoryOwner() = default; - MemoryAllocator* allocator() { return &allocator_; } + explicit MemoryOwner(std::shared_ptr allocator) + : MemoryAllocator(std::move(allocator)) {} // Post a reclaimer for some reclamation pass. void PostReclaimer(ReclamationPass pass, ReclamationFunction fn) { - static_cast(allocator_.get_internal_impl_ptr()) - ->PostReclaimer(pass, std::move(fn)); + impl()->PostReclaimer(pass, std::move(fn)); } // Rebind to a different quota. void Rebind(MemoryQuota* quota); + // Instantaneous memory pressure in the underlying quota. + double InstantaneousPressure() const { + return impl()->InstantaneousPressure(); + } + + template + OrphanablePtr MakeOrphanable(Args&&... args) { + return OrphanablePtr(New(std::forward(args)...)); + } + + // Name of this object + absl::string_view name() const { return impl()->name(); } + + // Is this object valid (ie has not been moved out of or reset) + bool is_valid() const { return impl() != nullptr; } + private: - MemoryAllocator allocator_; + const GrpcMemoryAllocatorImpl* impl() const { + return static_cast(get_internal_impl_ptr()); + } + + GrpcMemoryAllocatorImpl* impl() { + return static_cast(get_internal_impl_ptr()); + } }; // MemoryQuota tracks the amount of memory available as part of a ResourceQuota. class MemoryQuota final : public grpc_event_engine::experimental::MemoryAllocatorFactory { public: - MemoryQuota() : memory_quota_(std::make_shared()) { + explicit MemoryQuota(std::string name) + : memory_quota_(std::make_shared(std::move(name))) { memory_quota_->Start(); } ~MemoryQuota() override { @@ -336,24 +393,29 @@ class MemoryQuota final MemoryQuota(MemoryQuota&&) = default; MemoryQuota& operator=(MemoryQuota&&) = default; - MemoryAllocator CreateMemoryAllocator() override { - auto impl = std::make_shared(memory_quota_); - return MemoryAllocator(std::move(impl)); - } - - MemoryOwner CreateMemoryOwner() { - auto impl = std::make_shared(memory_quota_); - return MemoryOwner(std::move(impl)); - } + MemoryAllocator CreateMemoryAllocator(absl::string_view name) override; + MemoryOwner CreateMemoryOwner(absl::string_view name); // Resize the quota to new_size. void SetSize(size_t new_size) { memory_quota_->SetSize(new_size); } + // Return true if the instantaneous memory pressure is high. + bool IsMemoryPressureHigh() const { + static constexpr double kMemoryPressureHighThreshold = 0.9; + return memory_quota_->InstantaneousPressureAndMaxRecommendedAllocationSize() + .first > kMemoryPressureHighThreshold; + } + private: friend class MemoryOwner; std::shared_ptr memory_quota_; }; +using MemoryQuotaRefPtr = std::shared_ptr; +inline MemoryQuotaRefPtr MakeMemoryQuota(std::string name) { + return std::make_shared(std::move(name)); +} + } // namespace grpc_core #endif // GRPC_CORE_LIB_RESOURCE_QUOTA_MEMORY_QUOTA_H diff --git a/src/core/lib/resource_quota/resource_quota.cc b/src/core/lib/resource_quota/resource_quota.cc index cf4229bb4e5..ac8e3cef356 100644 --- a/src/core/lib/resource_quota/resource_quota.cc +++ b/src/core/lib/resource_quota/resource_quota.cc @@ -18,10 +18,16 @@ namespace grpc_core { -ResourceQuota::ResourceQuota() - : memory_quota_(std::make_shared()), +ResourceQuota::ResourceQuota(std::string name) + : memory_quota_(MakeMemoryQuota(std::move(name))), thread_quota_(MakeRefCounted()) {} ResourceQuota::~ResourceQuota() = default; +ResourceQuotaRefPtr ResourceQuota::Default() { + static auto default_resource_quota = + MakeResourceQuota("default_resource_quota").release(); + return default_resource_quota->Ref(); +} + } // namespace grpc_core diff --git a/src/core/lib/resource_quota/resource_quota.h b/src/core/lib/resource_quota/resource_quota.h index c43e4c80b0c..28a6156ea59 100644 --- a/src/core/lib/resource_quota/resource_quota.h +++ b/src/core/lib/resource_quota/resource_quota.h @@ -17,28 +17,42 @@ #include +#include + +#include "src/core/lib/gprpp/cpp_impl_of.h" #include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/thread_quota.h" namespace grpc_core { -class ResourceQuota : public RefCounted { +class ResourceQuota; +using ResourceQuotaRefPtr = RefCountedPtr; + +class ResourceQuota : public RefCounted, + public CppImplOf { public: - ResourceQuota(); + explicit ResourceQuota(std::string name); ~ResourceQuota() override; ResourceQuota(const ResourceQuota&) = delete; ResourceQuota& operator=(const ResourceQuota&) = delete; - std::shared_ptr memory_quota() { return memory_quota_; } + MemoryQuotaRefPtr memory_quota() { return memory_quota_; } const RefCountedPtr& thread_quota() { return thread_quota_; } + // The default global resource quota + static ResourceQuotaRefPtr Default(); + private: - std::shared_ptr memory_quota_; + MemoryQuotaRefPtr memory_quota_; RefCountedPtr thread_quota_; }; +inline ResourceQuotaRefPtr MakeResourceQuota(std::string name) { + return MakeRefCounted(std::move(name)); +} + } // namespace grpc_core #endif // GRPC_CORE_LIB_RESOURCE_QUOTA_RESOURCE_QUOTA_H diff --git a/src/core/lib/resource_quota/thread_quota.h b/src/core/lib/resource_quota/thread_quota.h index 0f236dd7afd..c0ae46da459 100644 --- a/src/core/lib/resource_quota/thread_quota.h +++ b/src/core/lib/resource_quota/thread_quota.h @@ -50,6 +50,8 @@ class ThreadQuota : public RefCounted { size_t max_ ABSL_GUARDED_BY(mu_) = std::numeric_limits::max(); }; +using ThreadQuotaPtr = RefCountedPtr; + } // namespace grpc_core #endif // GRPC_CORE_LIB_RESOURCE_QUOTA_THREAD_QUOTA_H diff --git a/src/core/lib/resource_quota/trace.cc b/src/core/lib/resource_quota/trace.cc new file mode 100644 index 00000000000..51e6cb01657 --- /dev/null +++ b/src/core/lib/resource_quota/trace.cc @@ -0,0 +1,19 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "src/core/lib/resource_quota/trace.h" + +grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota"); diff --git a/test/core/util/resource_user_util.h b/src/core/lib/resource_quota/trace.h similarity index 58% rename from test/core/util/resource_user_util.h rename to src/core/lib/resource_quota/trace.h index 397c0a5cbcd..8964746fea2 100644 --- a/test/core/util/resource_user_util.h +++ b/src/core/lib/resource_quota/trace.h @@ -1,4 +1,4 @@ -// Copyright 2021 The gRPC Authors +// Copyright 2021 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,14 +11,14 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#ifndef GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H -#define GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H -#include "src/core/lib/iomgr/resource_quota.h" +#ifndef GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H +#define GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H -grpc_resource_user* grpc_resource_user_create_unlimited( - grpc_resource_quota* resource_quota = nullptr); +#include -grpc_slice_allocator* grpc_slice_allocator_create_unlimited(); +#include "src/core/lib/debug/trace.h" -#endif // GRPC_TEST_CORE_UTIL_RESOURCE_USER_UTIL_H +extern grpc_core::TraceFlag grpc_resource_quota_trace; + +#endif // GRPC_CORE_LIB_RESOURCE_QUOTA_TRACE_H diff --git a/src/core/lib/security/credentials/external/aws_external_account_credentials.cc b/src/core/lib/security/credentials/external/aws_external_account_credentials.cc index 03dd4d59cc6..1a2e3ed4048 100644 --- a/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +++ b/src/core/lib/security/credentials/external/aws_external_account_credentials.cc @@ -166,13 +166,12 @@ void AwsExternalAccountCredentials::RetrieveRegion() { request.http.path = gpr_strdup(uri->path().c_str()); request.handshaker = uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRegion, this, nullptr); - grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, ctx_->deadline, &ctx_->closure, &ctx_->response); + grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, ctx_->deadline, + &ctx_->closure, &ctx_->response); grpc_http_request_destroy(&request.http); } @@ -214,13 +213,13 @@ void AwsExternalAccountCredentials::RetrieveRoleName() { request.http.path = gpr_strdup(uri->path().c_str()); request.handshaker = uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveRoleName, this, nullptr); - grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, ctx_->deadline, &ctx_->closure, &ctx_->response); + // TODO(ctiller): use the caller's resource quota. + grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, ctx_->deadline, + &ctx_->closure, &ctx_->response); grpc_http_request_destroy(&request.http); } @@ -274,13 +273,13 @@ void AwsExternalAccountCredentials::RetrieveSigningKeys() { request.http.path = gpr_strdup(uri->path().c_str()); request.handshaker = uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSigningKeys, this, nullptr); - grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, ctx_->deadline, &ctx_->closure, &ctx_->response); + // TODO(ctiller): use the caller's resource quota. + grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, ctx_->deadline, + &ctx_->closure, &ctx_->response); grpc_http_request_destroy(&request.http); } diff --git a/src/core/lib/security/credentials/external/external_account_credentials.cc b/src/core/lib/security/credentials/external/external_account_credentials.cc index dbcb1238459..cf1aafd118e 100644 --- a/src/core/lib/security/credentials/external/external_account_credentials.cc +++ b/src/core/lib/security/credentials/external/external_account_credentials.cc @@ -323,14 +323,13 @@ void ExternalAccountCredentials::ExchangeToken( body_parts.push_back(absl::StrFormat( "options=%s", UrlEncode(addtional_options_json.Dump()).c_str())); std::string body = absl::StrJoin(body_parts, "&"); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnExchangeToken, this, nullptr); - grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, body.c_str(), body.size(), ctx_->deadline, - &ctx_->closure, &ctx_->response); + grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, body.c_str(), + body.size(), ctx_->deadline, &ctx_->closure, + &ctx_->response); grpc_http_request_destroy(&request.http); } @@ -409,14 +408,14 @@ void ExternalAccountCredentials::ImpersenateServiceAccount() { uri->scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; std::string scope = absl::StrJoin(scopes_, " "); std::string body = absl::StrFormat("scope=%s", scope); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnImpersenateServiceAccount, this, nullptr); - grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, body.c_str(), body.size(), ctx_->deadline, - &ctx_->closure, &ctx_->response); + // TODO(ctiller): Use the callers resource quota. + grpc_httpcli_post(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, body.c_str(), + body.size(), ctx_->deadline, &ctx_->closure, + &ctx_->response); grpc_http_request_destroy(&request.http); } diff --git a/src/core/lib/security/credentials/external/url_external_account_credentials.cc b/src/core/lib/security/credentials/external/url_external_account_credentials.cc index b48bf71f43c..f97db1a8f26 100644 --- a/src/core/lib/security/credentials/external/url_external_account_credentials.cc +++ b/src/core/lib/security/credentials/external/url_external_account_credentials.cc @@ -139,13 +139,12 @@ void UrlExternalAccountCredentials::RetrieveSubjectToken( request.http.hdrs = headers; request.handshaker = url_.scheme() == "https" ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("external_account_credentials"); grpc_http_response_destroy(&ctx_->response); ctx_->response = {}; GRPC_CLOSURE_INIT(&ctx_->closure, OnRetrieveSubjectToken, this, nullptr); - grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, resource_quota, - &request, ctx_->deadline, &ctx_->closure, &ctx_->response); + grpc_httpcli_get(ctx_->httpcli_context, ctx_->pollent, + ResourceQuota::Default(), &request, ctx_->deadline, + &ctx_->closure, &ctx_->response); grpc_http_request_destroy(&request.http); } diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc index 18710c5ecac..2a34bcaf81e 100644 --- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc +++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc @@ -187,11 +187,9 @@ static int is_metadata_server_reachable() { request.host = const_cast(GRPC_COMPUTE_ENGINE_DETECTION_HOST); request.http.path = const_cast("/"); grpc_httpcli_context_init(&context); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("google_default_credentials"); grpc_httpcli_get( - &context, &detector.pollent, resource_quota, &request, - grpc_core::ExecCtx::Get()->Now() + max_detection_delay, + &context, &detector.pollent, grpc_core::ResourceQuota::Default(), + &request, grpc_core::ExecCtx::Get()->Now() + max_detection_delay, GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector, grpc_schedule_on_exec_ctx), &detector.response); diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 010ef78423d..d316c12135d 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -671,7 +671,6 @@ static void on_openid_config_retrieved(void* user_data, Json json = json_from_http(response); grpc_httpcli_request req; const char* jwks_uri; - grpc_resource_quota* resource_quota = nullptr; const Json* cur; /* TODO(jboeuf): Cache the jwks_uri in order to avoid this hop next time. */ @@ -700,9 +699,9 @@ static void on_openid_config_retrieved(void* user_data, /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host channel. This would allow us to cancel an authentication query when under extreme memory pressure. */ - resource_quota = grpc_resource_quota_create("jwt_verifier"); grpc_httpcli_get( - &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req, + &ctx->verifier->http_ctx, &ctx->pollent, + grpc_core::ResourceQuota::Default(), &req, grpc_core::ExecCtx::Get()->Now() + grpc_jwt_verifier_max_delay, GRPC_CLOSURE_CREATE(on_keys_retrieved, ctx, grpc_schedule_on_exec_ctx), &ctx->responses[HTTP_RESPONSE_KEYS]); @@ -765,7 +764,6 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { char* path_prefix = nullptr; const char* iss; grpc_httpcli_request req; - grpc_resource_quota* resource_quota = nullptr; memset(&req, 0, sizeof(grpc_httpcli_request)); req.handshaker = &grpc_httpcli_ssl; http_response_index rsp_idx; @@ -825,9 +823,9 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host channel. This would allow us to cancel an authentication query when under extreme memory pressure. */ - resource_quota = grpc_resource_quota_create("jwt_verifier"); grpc_httpcli_get( - &ctx->verifier->http_ctx, &ctx->pollent, resource_quota, &req, + &ctx->verifier->http_ctx, &ctx->pollent, + grpc_core::ResourceQuota::Default(), &req, grpc_core::ExecCtx::Get()->Now() + grpc_jwt_verifier_max_delay, http_cb, &ctx->responses[rsp_idx]); gpr_free(req.host); diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index df467fe4b1f..a00cb4ac37e 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -392,12 +392,11 @@ class grpc_compute_engine_token_fetcher_credentials const_cast(GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH); request.http.hdr_count = 1; request.http.hdrs = &header; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + /* TODO(ctiller): Carry the memory quota in ctx and share it with the host channel. This would allow us to cancel an authentication query when under extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials"); - grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline, + grpc_httpcli_get(http_context, pollent, grpc_core::ResourceQuota::Default(), + &request, deadline, GRPC_CLOSURE_INIT(&http_get_cb_closure_, response_cb, metadata_req, grpc_schedule_on_exec_ctx), &metadata_req->response); @@ -451,13 +450,12 @@ void grpc_google_refresh_token_credentials::fetch_oauth2( request.http.hdr_count = 1; request.http.hdrs = &header; request.handshaker = &grpc_httpcli_ssl; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + /* TODO(ctiller): Carry the memory quota in ctx and share it with the host channel. This would allow us to cancel an authentication query when under extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials_refresh"); - grpc_httpcli_post(httpcli_context, pollent, resource_quota, &request, - body.c_str(), body.size(), deadline, + grpc_httpcli_post(httpcli_context, pollent, + grpc_core::ResourceQuota::Default(), &request, body.c_str(), + body.size(), deadline, GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req, grpc_schedule_on_exec_ctx), &metadata_req->response); @@ -582,14 +580,12 @@ class StsTokenFetcherCredentials request.handshaker = (sts_url_.scheme() == "https") ? &grpc_httpcli_ssl : &grpc_httpcli_plaintext; - /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host + /* TODO(ctiller): Carry the memory quota in ctx and share it with the host channel. This would allow us to cancel an authentication query when under extreme memory pressure. */ - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("oauth2_credentials_refresh"); grpc_httpcli_post( - http_context, pollent, resource_quota, &request, body, body_length, - deadline, + http_context, pollent, grpc_core::ResourceQuota::Default(), &request, + body, body_length, deadline, GRPC_CLOSURE_INIT(&http_post_cb_closure_, response_cb, metadata_req, grpc_schedule_on_exec_ctx), &metadata_req->response); diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index f4af87e67f3..d10cb074a49 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -41,7 +41,7 @@ #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -58,9 +58,7 @@ static void destroy_channel(void* arg, grpc_error_handle error); grpc_channel* grpc_channel_create_with_builder( grpc_channel_stack_builder* builder, - grpc_channel_stack_type channel_stack_type, - grpc_resource_user* resource_user, size_t preallocated_bytes, - grpc_error_handle* error) { + grpc_channel_stack_type channel_stack_type, grpc_error_handle* error) { char* target = gpr_strdup(grpc_channel_stack_builder_get_target(builder)); grpc_channel_args* args = grpc_channel_args_copy( grpc_channel_stack_builder_get_channel_arguments(builder)); @@ -84,17 +82,9 @@ grpc_channel* grpc_channel_create_with_builder( } gpr_free(target); grpc_channel_args_destroy(args); - if (resource_user != nullptr) { - if (preallocated_bytes > 0) { - grpc_resource_user_free(resource_user, preallocated_bytes); - } - grpc_resource_user_unref(resource_user); - } return nullptr; } channel->target = target; - channel->resource_user = resource_user; - channel->preallocated_bytes = preallocated_bytes; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); channel->registration_table.Init(); @@ -233,8 +223,6 @@ grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* input_args, grpc_channel_stack_type channel_stack_type, grpc_transport* optional_transport, - grpc_resource_user* resource_user, - size_t preallocated_bytes, grpc_error_handle* error) { // We need to make sure that grpc_shutdown() does not shut things down // until after the channel is destroyed. However, the channel may not @@ -272,12 +260,6 @@ grpc_channel* grpc_channel_create(const char* target, if (!grpc_core::CoreConfiguration::Get().channel_init().CreateStack( builder, channel_stack_type)) { grpc_channel_stack_builder_destroy(builder); - if (resource_user != nullptr) { - if (preallocated_bytes > 0) { - grpc_resource_user_free(resource_user, preallocated_bytes); - } - grpc_resource_user_unref(resource_user); - } grpc_shutdown(); // Since we won't call destroy_channel(). return nullptr; } @@ -286,8 +268,8 @@ grpc_channel* grpc_channel_create(const char* target, if (grpc_channel_stack_type_is_client(channel_stack_type)) { CreateChannelzNode(builder); } - grpc_channel* channel = grpc_channel_create_with_builder( - builder, channel_stack_type, resource_user, preallocated_bytes, error); + grpc_channel* channel = + grpc_channel_create_with_builder(builder, channel_stack_type, error); if (channel == nullptr) { grpc_shutdown(); // Since we won't call destroy_channel(). } @@ -504,13 +486,6 @@ static void destroy_channel(void* arg, grpc_error_handle /*error*/) { } grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CHANNEL(channel)); channel->registration_table.Destroy(); - if (channel->resource_user != nullptr) { - if (channel->preallocated_bytes > 0) { - grpc_resource_user_free(channel->resource_user, - channel->preallocated_bytes); - } - grpc_resource_user_unref(channel->resource_user); - } gpr_free(channel->target); gpr_free(channel); // See comment in grpc_channel_create() for why we do this. diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 353df77c783..f047ce5ba93 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -27,22 +27,15 @@ #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/surface/channel_stack_type.h" #include "src/core/lib/transport/metadata.h" /// Creates a grpc_channel. -/// -/// If the \a resource_user is not null, \a preallocated_bytes may have been -/// allocated on that resource_user for use by the channel. These bytes will be -/// freed from the resource_user upon channel destruction. -/// -/// Takes ownership of a \a resource_user ref. grpc_channel* grpc_channel_create(const char* target, const grpc_channel_args* args, grpc_channel_stack_type channel_stack_type, grpc_transport* optional_transport, - grpc_resource_user* resource_user, - size_t preallocated_bytes, grpc_error_handle* error); /** The same as grpc_channel_destroy, but doesn't create an ExecCtx, and so @@ -54,7 +47,6 @@ void grpc_channel_destroy_internal(grpc_channel* channel); grpc_channel* grpc_channel_create_with_builder( grpc_channel_stack_builder* builder, grpc_channel_stack_type channel_stack_type, - grpc_resource_user* resource_user, size_t preallocated_bytes, grpc_error_handle* error = nullptr); /** Create a call given a grpc_channel, in order to call \a method. @@ -109,8 +101,6 @@ struct grpc_channel { grpc_compression_options compression_options; gpr_atm call_size_estimate; - grpc_resource_user* resource_user; - size_t preallocated_bytes; // TODO(vjpai): Once the grpc_channel is allocated via new rather than malloc, // expand the members of the CallRegistrationTable directly into diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 3bc610c21ad..13a9508ce8c 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -42,7 +42,6 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" -#include "src/core/lib/iomgr/resource_quota.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index a1fbd069c95..f54dc72e38b 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" @@ -184,9 +185,13 @@ grpc_channel* grpc_lame_client_channel_create(const char* target, GRPC_ERROR_INT_GRPC_STATUS, error_code), GRPC_ERROR_STR_GRPC_MESSAGE, error_message); grpc_arg error_arg = grpc_core::MakeLameClientErrorArg(&error); - grpc_channel_args args = {1, &error_arg}; + grpc_channel_args* args0 = + grpc_channel_args_copy_and_add(nullptr, &error_arg, 1); + grpc_channel_args* args = grpc_core::EnsureResourceQuotaInChannelArgs(args0); + grpc_channel_args_destroy(args0); grpc_channel* channel = grpc_channel_create( - target, &args, GRPC_CLIENT_LAME_CHANNEL, nullptr, nullptr, 0, nullptr); + target, args, GRPC_CLIENT_LAME_CHANNEL, nullptr, nullptr); + grpc_channel_args_destroy(args); GRPC_ERROR_UNREF(error); return channel; } diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5f85523ce9c..834a3b2a49f 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -46,6 +46,7 @@ #include "src/core/lib/gprpp/mpscq.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/call.h" @@ -600,13 +601,11 @@ void Server::Start() { grpc_error_handle Server::SetupTransport( grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - const RefCountedPtr& socket_node, - grpc_resource_user* resource_user, size_t preallocated_bytes) { + const RefCountedPtr& socket_node) { // Create channel. grpc_error_handle error = GRPC_ERROR_NONE; - grpc_channel* channel = - grpc_channel_create(nullptr, args, GRPC_SERVER_CHANNEL, transport, - resource_user, preallocated_bytes, &error); + grpc_channel* channel = grpc_channel_create( + nullptr, args, GRPC_SERVER_CHANNEL, transport, &error); if (channel == nullptr) { return error; } @@ -1477,8 +1476,12 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { grpc_core::ExecCtx exec_ctx; args = grpc_channel_args_remove_grpc_internal(args); GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved)); + grpc_channel_args* new_args = + grpc_core::EnsureResourceQuotaInChannelArgs(args); grpc_server* c_server = new grpc_server; - c_server->core_server = grpc_core::MakeOrphanable(args); + c_server->core_server = + grpc_core::MakeOrphanable(new_args); + grpc_channel_args_destroy(new_args); grpc_channel_args_destroy(args); return c_server; } diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index 3e1a4a9a0a0..d0c78c4587a 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -34,6 +34,7 @@ #include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/transport/transport.h" @@ -130,9 +131,7 @@ class Server : public InternallyRefCounted { grpc_error_handle SetupTransport( grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args, - const RefCountedPtr& socket_node, - grpc_resource_user* resource_user = nullptr, - size_t preallocated_bytes = 0); + const RefCountedPtr& socket_node); void RegisterCompletionQueue(grpc_completion_queue* cq); diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index dd638e6ec2f..dffe1e12ced 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -202,28 +202,16 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( const ByteBuffer& request, std::string* service_name) { - std::vector slices; - if (!request.Dump(&slices).ok()) return false; + Slice slice; + if (!request.DumpToSingleSlice(&slice).ok()) return false; uint8_t* request_bytes = nullptr; size_t request_size = 0; - if (slices.size() == 1) { - request_bytes = const_cast(slices[0].begin()); - request_size = slices[0].size(); - } else if (slices.size() > 1) { - request_bytes = static_cast(gpr_malloc(request.Length())); - uint8_t* copy_to = request_bytes; - for (size_t i = 0; i < slices.size(); i++) { - memcpy(copy_to, slices[i].begin(), slices[i].size()); - copy_to += slices[i].size(); - } - } + request_bytes = const_cast(slice.begin()); + request_size = slice.size(); upb::Arena arena; grpc_health_v1_HealthCheckRequest* request_struct = grpc_health_v1_HealthCheckRequest_parse( reinterpret_cast(request_bytes), request_size, arena.ptr()); - if (slices.size() > 1) { - gpr_free(request_bytes); - } if (request_struct == nullptr) { return false; } diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index d257ae8dda6..ee7eed1d632 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -50,18 +50,16 @@ ThreadManager::WorkerThread::~WorkerThread() { thd_.Join(); } -ThreadManager::ThreadManager(const char* name, - grpc_resource_quota* resource_quota, +ThreadManager::ThreadManager(const char*, grpc_resource_quota* resource_quota, int min_pollers, int max_pollers) : shutdown_(false), + thread_quota_( + grpc_core::ResourceQuotaFromC(resource_quota)->thread_quota()), num_pollers_(0), min_pollers_(min_pollers), max_pollers_(max_pollers == -1 ? INT_MAX : max_pollers), num_threads_(0), - max_active_threads_sofar_(0) { - resource_user_ = - grpc_resource_user_create(resource_quota, name != nullptr ? name : ""); -} + max_active_threads_sofar_(0) {} ThreadManager::~ThreadManager() { { @@ -69,8 +67,6 @@ ThreadManager::~ThreadManager() { GPR_ASSERT(num_threads_ == 0); } - grpc_core::ExecCtx exec_ctx; // grpc_resource_user_unref needs an exec_ctx - grpc_resource_user_unref(resource_user_); CleanupCompletedThreads(); } @@ -111,7 +107,7 @@ void ThreadManager::MarkAsCompleted(WorkerThread* thd) { } // Give a thread back to the resource quota - grpc_resource_user_free_threads(resource_user_, 1); + thread_quota_->Release(1); } void ThreadManager::CleanupCompletedThreads() { @@ -126,7 +122,7 @@ void ThreadManager::CleanupCompletedThreads() { } void ThreadManager::Initialize() { - if (!grpc_resource_user_allocate_threads(resource_user_, min_pollers_)) { + if (!thread_quota_->Reserve(min_pollers_)) { gpr_log(GPR_ERROR, "No thread quota available to even create the minimum required " "polling threads (i.e %d). Unable to start the thread manager", @@ -173,7 +169,7 @@ void ThreadManager::MainWorkLoop() { // quota available to create a new thread, start a new poller thread bool resource_exhausted = false; if (!shutdown_ && num_pollers_ < min_pollers_) { - if (grpc_resource_user_allocate_threads(resource_user_, 1)) { + if (thread_quota_->Reserve(1)) { // We can allocate a new poller thread num_pollers_++; num_threads_++; diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index aae24177873..4c49854d32e 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -22,11 +22,12 @@ #include #include +#include #include #include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/thd.h" -#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/resource_quota/api.h" namespace grpc { @@ -154,7 +155,7 @@ class ThreadManager { // object (that contains the actual max thread quota) and a grpc_resource_user // object through which quota is requested whenever new threads need to be // created - grpc_resource_user* resource_user_; + grpc_core::ThreadQuotaPtr thread_quota_; // Number of threads doing polling int num_pollers_; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index f67264b114c..693da702320 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -365,6 +365,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/event_engine/channel_args_endpoint_config.cc', 'src/core/lib/event_engine/event_engine.cc', 'src/core/lib/event_engine/event_engine_factory.cc', + 'src/core/lib/event_engine/memory_allocator.cc', 'src/core/lib/event_engine/sockaddr.cc', 'src/core/lib/gpr/alloc.cc', 'src/core/lib/gpr/atm.cc', @@ -472,7 +473,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/resolve_address_custom.cc', 'src/core/lib/iomgr/resolve_address_posix.cc', 'src/core/lib/iomgr/resolve_address_windows.cc', - 'src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/iomgr/socket_factory_posix.cc', 'src/core/lib/iomgr/socket_mutator.cc', 'src/core/lib/iomgr/socket_utils_common_posix.cc', @@ -514,6 +514,12 @@ CORE_SOURCE_FILES = [ 'src/core/lib/matchers/matchers.cc', 'src/core/lib/profiling/basic_timers.cc', 'src/core/lib/profiling/stap_timers.cc', + 'src/core/lib/promise/activity.cc', + 'src/core/lib/resource_quota/api.cc', + 'src/core/lib/resource_quota/memory_quota.cc', + 'src/core/lib/resource_quota/resource_quota.cc', + 'src/core/lib/resource_quota/thread_quota.cc', + 'src/core/lib/resource_quota/trace.cc', 'src/core/lib/security/authorization/authorization_policy_provider_vtable.cc', 'src/core/lib/security/authorization/evaluate_args.cc', 'src/core/lib/security/authorization/sdk_server_authz_filter.cc', diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index 85a70b33239..2caf2e59d9f 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -31,11 +31,11 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/endpoint_pair.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" #include "test/core/end2end/cq_verifier.h" -#include "test/core/util/resource_user_util.h" #define MIN_HTTP2_FRAME_SIZE 9 @@ -212,8 +212,10 @@ void grpc_run_bad_client_test( GRPC_BAD_CLIENT_REGISTERED_HOST, GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); grpc_server_start(a.server); - transport = grpc_create_chttp2_transport( - nullptr, sfd.server, false, grpc_resource_user_create_unlimited()); + grpc_channel_args* channel_args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + transport = grpc_create_chttp2_transport(channel_args, sfd.server, false); + grpc_channel_args_destroy(channel_args); server_setup_transport(&a, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index 5d8e19f5665..772a931a75f 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -42,7 +42,6 @@ #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" static void* tag(intptr_t t) { return reinterpret_cast(t); } @@ -94,15 +93,14 @@ static void client_setup_transport(grpc_transport* transport) { * GRPC_CLIENT_DIRECT_CHANNEL */ g_ctx.client = grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, nullptr); + transport, nullptr); grpc_channel_args_destroy(args); } static void init_client() { grpc_core::ExecCtx exec_ctx; grpc_transport* transport; - transport = grpc_create_chttp2_transport( - nullptr, g_ctx.ep->client, true, grpc_resource_user_create_unlimited()); + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->client, true); client_setup_transport(transport); GPR_ASSERT(g_ctx.client); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); @@ -115,8 +113,7 @@ static void init_server() { g_ctx.server = grpc_server_create(nullptr, nullptr); grpc_server_register_completion_queue(g_ctx.server, g_ctx.cq, nullptr); grpc_server_start(g_ctx.server); - transport = grpc_create_chttp2_transport( - nullptr, g_ctx.ep->server, false, grpc_resource_user_create_unlimited()); + transport = grpc_create_chttp2_transport(nullptr, g_ctx.ep->server, false); server_setup_transport(transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); } diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc index c3e33553216..19b8ead5540 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.cc +++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc @@ -35,6 +35,7 @@ #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/port.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" @@ -47,7 +48,6 @@ struct custom_fixture_data { grpc_endpoint_pair ep; - grpc_resource_quota* resource_quota; }; static void server_setup_transport(void* ts, grpc_transport* transport) { @@ -79,9 +79,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) { grpc_channel_args* args = grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); grpc_error_handle error = GRPC_ERROR_NONE; - cs->f->client = - grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, &error); + cs->f->client = grpc_channel_create( + "socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error); grpc_channel_args_destroy(args); if (cs->f->client != nullptr) { grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); @@ -99,7 +98,7 @@ static void client_setup_transport(void* ts, grpc_transport* transport) { } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( - grpc_channel_args* client_args, grpc_channel_args* /*server_args*/) { + grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) { custom_fixture_data* fixture_data = static_cast( gpr_malloc(sizeof(custom_fixture_data))); grpc_end2end_test_fixture f; @@ -107,8 +106,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( f.fixture_data = fixture_data; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - fixture_data->resource_quota = - grpc_resource_quota_from_channel_args(client_args, true); fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", nullptr); return f; } @@ -121,10 +118,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport( - client_args, fixture_data->ep.client, true, - grpc_resource_user_create(fixture_data->resource_quota, - "client_transport")); + client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args); + transport = + grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true); + grpc_channel_args_destroy(client_args); client_setup_transport(&cs, transport); GPR_ASSERT(f->client); } @@ -138,17 +135,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f, f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport( - server_args, fixture_data->ep.server, false, - grpc_resource_user_create(fixture_data->resource_quota, - "server_transport")); + server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args); + transport = + grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false); + grpc_channel_args_destroy(server_args); server_setup_transport(f, transport); } static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; - auto* fixture_data = static_cast(f->fixture_data); - grpc_resource_quota_unref(fixture_data->resource_quota); gpr_free(f->fixture_data); } diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc index a8b61152e6e..9e9dabcb24d 100644 --- a/test/core/end2end/fixtures/h2_sockpair.cc +++ b/test/core/end2end/fixtures/h2_sockpair.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" @@ -42,7 +43,6 @@ struct custom_fixture_data { grpc_endpoint_pair ep; - grpc_resource_quota* resource_quota; }; static void server_setup_transport(void* ts, grpc_transport* transport) { @@ -75,9 +75,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) { grpc_channel_args* args = grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); grpc_error_handle error = GRPC_ERROR_NONE; - cs->f->client = - grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, &error); + cs->f->client = grpc_channel_create( + "socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error); grpc_channel_args_destroy(args); if (cs->f->client != nullptr) { grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); @@ -95,7 +94,7 @@ static void client_setup_transport(void* ts, grpc_transport* transport) { } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( - grpc_channel_args* client_args, grpc_channel_args* /*server_args*/) { + grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) { custom_fixture_data* fixture_data = static_cast( gpr_malloc(sizeof(custom_fixture_data))); grpc_end2end_test_fixture f; @@ -103,8 +102,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( f.fixture_data = fixture_data; f.cq = grpc_completion_queue_create_for_next(nullptr); f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - fixture_data->resource_quota = - grpc_resource_quota_from_channel_args(client_args, true); fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", nullptr); return f; } @@ -117,10 +114,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport( - client_args, fixture_data->ep.client, true, - grpc_resource_user_create(fixture_data->resource_quota, - "client_transport")); + client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args); + transport = + grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true); + grpc_channel_args_destroy(client_args); client_setup_transport(&cs, transport); GPR_ASSERT(f->client); } @@ -134,17 +131,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f, f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport( - server_args, fixture_data->ep.server, false, - grpc_resource_user_create(fixture_data->resource_quota, - "server_transport")); + server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args); + transport = + grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false); + grpc_channel_args_destroy(server_args); server_setup_transport(f, transport); } static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; - auto* fixture_data = static_cast(f->fixture_data); - grpc_resource_quota_unref(fixture_data->resource_quota); gpr_free(f->fixture_data); } diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc index 35586267123..6da339d1fed 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/iomgr/endpoint_pair.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" @@ -42,7 +43,6 @@ struct custom_fixture_data { grpc_endpoint_pair ep; - grpc_resource_quota* resource_quota; }; static void server_setup_transport(void* ts, grpc_transport* transport) { @@ -75,9 +75,8 @@ static void client_setup_transport(void* ts, grpc_transport* transport) { grpc_channel_args* args = grpc_channel_args_copy_and_add(cs->client_args, &authority_arg, 1); grpc_error_handle error = GRPC_ERROR_NONE; - cs->f->client = - grpc_channel_create("socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, &error); + cs->f->client = grpc_channel_create( + "socketpair-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, &error); grpc_channel_args_destroy(args); if (cs->f->client != nullptr) { grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); @@ -114,8 +113,6 @@ static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( a[2].type = GRPC_ARG_INTEGER; a[2].value.integer = 1; grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - fixture_data->resource_quota = - grpc_resource_quota_from_channel_args(&args, true); fixture_data->ep = grpc_iomgr_create_endpoint_pair("fixture", &args); return f; } @@ -128,10 +125,10 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture* f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport( - client_args, fixture_data->ep.client, true, - grpc_resource_user_create(fixture_data->resource_quota, - "client_transport")); + client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args); + transport = + grpc_create_chttp2_transport(client_args, fixture_data->ep.client, true); + grpc_channel_args_destroy(client_args); client_setup_transport(&cs, transport); GPR_ASSERT(f->client); } @@ -145,17 +142,15 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture* f, f->server = grpc_server_create(server_args, nullptr); grpc_server_register_completion_queue(f->server, f->cq, nullptr); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport( - server_args, fixture_data->ep.server, false, - grpc_resource_user_create(fixture_data->resource_quota, - "server_transport")); + server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args); + transport = + grpc_create_chttp2_transport(server_args, fixture_data->ep.server, false); + grpc_channel_args_destroy(server_args); server_setup_transport(f, transport); } static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture* f) { grpc_core::ExecCtx exec_ctx; - auto* fixture_data = static_cast(f->fixture_data); - grpc_resource_quota_unref(fixture_data->resource_quota); gpr_free(f->fixture_data); } diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index 93f4f1bd967..4d3a9d7b4e9 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -48,10 +48,10 @@ #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/b64.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/port.h" -#include "test/core/util/resource_user_util.h" struct grpc_end2end_http_proxy { grpc_end2end_http_proxy() @@ -536,10 +536,12 @@ static void on_read_request_done_locked(void* arg, grpc_error_handle error) { grpc_core::ExecCtx::Get()->Now() + 10 * GPR_MS_PER_SEC; GRPC_CLOSURE_INIT(&conn->on_server_connect_done, on_server_connect_done, conn, grpc_schedule_on_exec_ctx); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); grpc_tcp_client_connect(&conn->on_server_connect_done, &conn->server_endpoint, - grpc_slice_allocator_create_unlimited(), - conn->pollset_set, nullptr, + conn->pollset_set, args, &resolved_addresses->addrs[0], deadline); + grpc_channel_args_destroy(args); grpc_resolved_addresses_destroy(resolved_addresses); } @@ -610,12 +612,9 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( proxy->proxy_name = grpc_core::JoinHostPort("localhost", proxy_port); gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.c_str()); // Create TCP server. - proxy->channel_args = grpc_channel_args_copy(args); - grpc_error_handle error = grpc_tcp_server_create( - nullptr, proxy->channel_args, - grpc_slice_allocator_factory_create( - grpc_resource_quota_from_channel_args(args, true)), - &proxy->server); + proxy->channel_args = grpc_core::EnsureResourceQuotaInChannelArgs(args); + grpc_error_handle error = + grpc_tcp_server_create(nullptr, proxy->channel_args, &proxy->server); GPR_ASSERT(error == GRPC_ERROR_NONE); // Bind to port. grpc_resolved_address resolved_addr; diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index c8cb41fb6c8..028275411c7 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -150,34 +150,29 @@ static void my_cancel_ares_request_locked(grpc_ares_request* request) { //////////////////////////////////////////////////////////////////////////////// // client connection -static void sched_connect(grpc_closure* closure, - grpc_slice_allocator* slice_allocator, - grpc_endpoint** ep, gpr_timespec deadline); +static void sched_connect(grpc_closure* closure, grpc_endpoint** ep, + gpr_timespec deadline); typedef struct { grpc_timer timer; grpc_closure* closure; grpc_endpoint** ep; gpr_timespec deadline; - grpc_slice_allocator* slice_allocator; } future_connect; static void do_connect(void* arg, grpc_error_handle error) { future_connect* fc = static_cast(arg); if (error != GRPC_ERROR_NONE) { - grpc_slice_allocator_destroy(fc->slice_allocator); *fc->ep = nullptr; grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_REF(error)); } else if (g_server != nullptr) { - grpc_slice_allocator_destroy(fc->slice_allocator); grpc_endpoint* client; grpc_endpoint* server; grpc_passthru_endpoint_create(&client, &server, nullptr); *fc->ep = client; grpc_transport* transport = grpc_create_chttp2_transport( - nullptr, server, false, - grpc_resource_user_create(g_resource_quota, "transport-user")); + g_server->core_server->channel_args(), server, false); GPR_ASSERT(GRPC_LOG_IF_ERROR("SetupTransport", g_server->core_server->SetupTransport( transport, nullptr, nullptr, nullptr))); @@ -185,17 +180,15 @@ static void do_connect(void* arg, grpc_error_handle error) { grpc_core::ExecCtx::Run(DEBUG_LOCATION, fc->closure, GRPC_ERROR_NONE); } else { - sched_connect(fc->closure, fc->slice_allocator, fc->ep, fc->deadline); + sched_connect(fc->closure, fc->ep, fc->deadline); } gpr_free(fc); } -static void sched_connect(grpc_closure* closure, - grpc_slice_allocator* slice_allocator, - grpc_endpoint** ep, gpr_timespec deadline) { +static void sched_connect(grpc_closure* closure, grpc_endpoint** ep, + gpr_timespec deadline) { if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) { *ep = nullptr; - grpc_slice_allocator_destroy(slice_allocator); grpc_core::ExecCtx::Run( DEBUG_LOCATION, closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Connect deadline exceeded")); @@ -206,19 +199,17 @@ static void sched_connect(grpc_closure* closure, fc->closure = closure; fc->ep = ep; fc->deadline = deadline; - fc->slice_allocator = slice_allocator; grpc_timer_init( &fc->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(), GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx)); } static void my_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* /*interested_parties*/, const grpc_channel_args* /*channel_args*/, const grpc_resolved_address* /*addr*/, grpc_millis deadline) { - sched_connect(closure, slice_allocator, ep, + sched_connect(closure, ep, grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC)); } diff --git a/test/core/end2end/fuzzers/client_fuzzer.cc b/test/core/end2end/fuzzers/client_fuzzer.cc index bfc1c182c6b..9f157f95b04 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.cc +++ b/test/core/end2end/fuzzers/client_fuzzer.cc @@ -24,6 +24,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" #include "test/core/util/mock_endpoint.h" @@ -47,23 +48,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_resource_quota* resource_quota = grpc_resource_quota_create("context_list_test"); - grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create( - discard_write, - grpc_slice_allocator_create(resource_quota, "mock_endpoint")); + grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write); grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); - grpc_transport* transport = grpc_create_chttp2_transport( - nullptr, mock_endpoint, true, - grpc_resource_user_create(resource_quota, "mock_transport")); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_transport* transport = + grpc_create_chttp2_transport(args, mock_endpoint, true); + grpc_channel_args_destroy(args); grpc_resource_quota_unref(resource_quota); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); grpc_arg authority_arg = grpc_channel_arg_string_create( const_cast(GRPC_ARG_DEFAULT_AUTHORITY), const_cast("test-authority")); - grpc_channel_args* args = - grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1); - grpc_channel* channel = - grpc_channel_create("test-target", args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, nullptr); + args = grpc_channel_args_copy_and_add(nullptr, &authority_arg, 1); + grpc_channel* channel = grpc_channel_create( + "test-target", args, GRPC_CLIENT_DIRECT_CHANNEL, transport, nullptr); grpc_channel_args_destroy(args); grpc_slice host = grpc_slice_from_static_string("localhost"); grpc_call* call = grpc_channel_create_call( diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc index 418676a5cbc..2cee90f5c97 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.cc +++ b/test/core/end2end/fuzzers/server_fuzzer.cc @@ -20,6 +20,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/server.h" #include "test/core/util/mock_endpoint.h" @@ -42,9 +43,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_core::Executor::SetThreadingAll(false); grpc_resource_quota* resource_quota = grpc_resource_quota_create("context_list_test"); - grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create( - discard_write, - grpc_slice_allocator_create(resource_quota, "mock_endpoint")); + grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write); grpc_mock_endpoint_put_read( mock_endpoint, grpc_slice_from_copied_buffer((const char*)data, size)); grpc_server* server = grpc_server_create(nullptr, nullptr); @@ -53,9 +52,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // TODO(ctiller): add more registered methods (one for POST, one for PUT) grpc_server_register_method(server, "/reg", nullptr, {}, 0); grpc_server_start(server); - grpc_transport* transport = grpc_create_chttp2_transport( - nullptr, mock_endpoint, false, - grpc_resource_user_create(resource_quota, "mock_transport")); + grpc_channel_args* channel_args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_transport* transport = + grpc_create_chttp2_transport(channel_args, mock_endpoint, false); + grpc_channel_args_destroy(channel_args); grpc_resource_quota_unref(resource_quota); GPR_ASSERT(GRPC_LOG_IF_ERROR("SetupTransport", server->core_server->SetupTransport( diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 71027af2b37..b2a6b67aefe 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -28,6 +28,7 @@ def _fixture_options( tracing = False, _platforms = ["windows", "linux", "mac", "posix"], is_inproc = False, + is_1byte = False, is_http2 = True, supports_proxy_auth = False, supports_write_buffering = True, @@ -42,6 +43,7 @@ def _fixture_options( secure = secure, tracing = tracing, is_inproc = is_inproc, + is_1byte = is_1byte, is_http2 = is_http2, supports_proxy_auth = supports_proxy_auth, supports_write_buffering = supports_write_buffering, @@ -76,6 +78,7 @@ END2END_FIXTURES = { fullstack = False, dns_resolver = False, client_channel = False, + is_1byte = True, ), "h2_sockpair": _fixture_options( fullstack = False, @@ -151,6 +154,7 @@ END2END_NOSEC_FIXTURES = { dns_resolver = False, client_channel = False, secure = False, + is_1byte = True, ), "h2_sockpair": _fixture_options( fullstack = False, @@ -184,6 +188,7 @@ def _test_options( secure = False, traceable = False, exclude_inproc = False, + exclude_1byte = False, needs_http2 = False, needs_proxy_auth = False, needs_write_buffering = False, @@ -198,6 +203,7 @@ def _test_options( secure = secure, traceable = traceable, exclude_inproc = exclude_inproc, + exclude_1byte = exclude_1byte, needs_http2 = needs_http2, needs_proxy_auth = needs_proxy_auth, needs_write_buffering = needs_write_buffering, @@ -215,6 +221,7 @@ END2END_TESTS = { proxyable = False, # TODO(b/151212019): Test case known to be flaky under epoll1. exclude_pollers = ["epoll1"], + exclude_1byte = True, ), "call_creds": _test_options(secure = True), "call_host_override": _test_options( @@ -255,9 +262,9 @@ END2END_TESTS = { ), "high_initial_seqno": _test_options(), "idempotent_request": _test_options(), - "invoke_large_request": _test_options(), + "invoke_large_request": _test_options(exclude_1byte = True), "keepalive_timeout": _test_options(proxyable = False, needs_http2 = True), - "large_metadata": _test_options(), + "large_metadata": _test_options(exclude_1byte = True), "max_concurrent_streams": _test_options( proxyable = False, exclude_inproc = True, @@ -269,7 +276,7 @@ END2END_TESTS = { "no_error_on_hotpath": _test_options(proxyable = False), "no_logging": _test_options(traceable = False), "no_op": _test_options(), - "payload": _test_options(), + "payload": _test_options(exclude_1byte = True), # TODO(juanlishen): This is disabled for now because it depends on some generated functions in # end2end_tests.cc, which are not generated because they would depend on OpenCensus while # OpenCensus can only be built via Bazel so far. @@ -357,8 +364,9 @@ END2END_TESTS = { "stream_compression_compressed_payload": _test_options( proxyable = False, exclude_inproc = True, + exclude_1byte = True, ), - "stream_compression_payload": _test_options(exclude_inproc = True), + "stream_compression_payload": _test_options(exclude_inproc = True, exclude_1byte = True), "stream_compression_ping_pong_streaming": _test_options(exclude_inproc = True), "trailing_metadata": _test_options(), "authority_not_supported": _test_options(), @@ -387,6 +395,9 @@ def _compatible(fopt, topt): if topt.exclude_inproc: if fopt.is_inproc: return False + if topt.exclude_1byte: + if fopt.is_1byte: + return False if topt.needs_http2: if not fopt.is_http2: return False diff --git a/test/core/end2end/tests/binary_metadata.cc b/test/core/end2end/tests/binary_metadata.cc index ebc64a94d23..67066e1407e 100644 --- a/test/core/end2end/tests/binary_metadata.cc +++ b/test/core/end2end/tests/binary_metadata.cc @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/resource_quota/api.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/end2end_tests.h" @@ -35,9 +36,13 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); + client_args = grpc_core::EnsureResourceQuotaInChannelArgs(client_args); + server_args = grpc_core::EnsureResourceQuotaInChannelArgs(server_args); f = config.create_fixture(client_args, server_args); config.init_server(&f, server_args); config.init_client(&f, client_args); + grpc_channel_args_destroy(client_args); + grpc_channel_args_destroy(server_args); return f; } diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index 5b2a3c6bf87..9bb380d45fd 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -285,6 +285,18 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "cpp_impl_of_test", + srcs = ["cpp_impl_of_test.cc"], + external_deps = ["gtest"], + language = "c++", + uses_polling = False, + deps = [ + "//:cpp_impl_of", + "//test/core/util:grpc_suppressions", + ], +) + grpc_cc_test( name = "chunked_vector_test", srcs = ["chunked_vector_test.cc"], diff --git a/test/core/gprpp/cpp_impl_of_test.cc b/test/core/gprpp/cpp_impl_of_test.cc new file mode 100644 index 00000000000..d610c2d27ce --- /dev/null +++ b/test/core/gprpp/cpp_impl_of_test.cc @@ -0,0 +1,33 @@ +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/core/lib/gprpp/cpp_impl_of.h" + +#include + +typedef struct grpc_foo grpc_foo; + +namespace grpc_core { +namespace { +class Foo : public CppImplOf {}; +} // namespace + +TEST(CppImplOfTest, CreateDestroy) { delete Foo::FromC((new Foo())->c_ptr()); } + +} // namespace grpc_core + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/http/format_request_test.cc b/test/core/http/format_request_test.cc index d4d1be808d5..24ee0014841 100644 --- a/test/core/http/format_request_test.cc +++ b/test/core/http/format_request_test.cc @@ -20,6 +20,7 @@ #include +#include #include #include "test/core/util/test_config.h" diff --git a/test/core/http/httpcli_test.cc b/test/core/http/httpcli_test.cc index dbc04716c07..4946da3dcdb 100644 --- a/test/core/http/httpcli_test.cc +++ b/test/core/http/httpcli_test.cc @@ -78,9 +78,9 @@ static void test_get(int port) { grpc_http_response response; response = {}; - grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_get"); grpc_httpcli_get( - &g_context, &g_pops, resource_quota, &req, n_seconds_time(15), + &g_context, &g_pops, grpc_core::ResourceQuota::Default(), &req, + n_seconds_time(15), GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx), &response); gpr_mu_lock(g_mu); @@ -116,9 +116,9 @@ static void test_post(int port) { grpc_http_response response; response = {}; - grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_post"); grpc_httpcli_post( - &g_context, &g_pops, resource_quota, &req, "hello", 5, n_seconds_time(15), + &g_context, &g_pops, grpc_core::ResourceQuota::Default(), &req, "hello", + 5, n_seconds_time(15), GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx), &response); gpr_mu_lock(g_mu); diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc index 07e46ffa7c4..41372bf5945 100644 --- a/test/core/http/httpscli_test.cc +++ b/test/core/http/httpscli_test.cc @@ -81,9 +81,9 @@ static void test_get(int port) { grpc_http_response response; response = {}; - grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_get"); grpc_httpcli_get( - &g_context, &g_pops, resource_quota, &req, n_seconds_time(15), + &g_context, &g_pops, grpc_core::ResourceQuota::Default(), &req, + n_seconds_time(15), GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx), &response); gpr_mu_lock(g_mu); @@ -120,9 +120,9 @@ static void test_post(int port) { grpc_http_response response; response = {}; - grpc_resource_quota* resource_quota = grpc_resource_quota_create("test_post"); grpc_httpcli_post( - &g_context, &g_pops, resource_quota, &req, "hello", 5, n_seconds_time(15), + &g_context, &g_pops, grpc_core::ResourceQuota::Default(), &req, "hello", + 5, n_seconds_time(15), GRPC_CLOSURE_CREATE(on_finish, &response, grpc_schedule_on_exec_ctx), &response); gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 610527406f9..4b56aa1fae4 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -226,17 +226,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "resource_quota_test", - srcs = ["resource_quota_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "socket_utils_test", srcs = ["socket_utils_test.cc"], diff --git a/test/core/iomgr/fd_conservation_posix_test.cc b/test/core/iomgr/fd_conservation_posix_test.cc index 8af8949d142..9bc1e6b6189 100644 --- a/test/core/iomgr/fd_conservation_posix_test.cc +++ b/test/core/iomgr/fd_conservation_posix_test.cc @@ -18,6 +18,7 @@ #include +#include #include #include "src/core/lib/iomgr/endpoint_pair.h" diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm index fd3253fa13c..4b247ac1add 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamClientTests.mm @@ -24,16 +24,16 @@ #include +#include #include #include #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_client.h" -#include "test/core/util/resource_user_util.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/test_config.h" -// static int g_connections_complete = 0; static gpr_mu g_mu; static int g_connections_complete = 0; static grpc_endpoint* g_connecting = nullptr; @@ -103,8 +103,10 @@ static void must_fail(void* arg, grpc_error_handle error) { /* connect to it */ GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); GRPC_CLOSURE_INIT(&done, must_succeed, nullptr, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect(&done, &g_connecting, grpc_slice_allocator_create_unlimited(), nullptr, - nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args* args = grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_tcp_client_connect(&done, &g_connecting, nullptr, args, &resolved_addr, + GRPC_MILLIS_INF_FUTURE); + grpc_channel_args_destroy(args); /* await the connection */ do { @@ -158,8 +160,10 @@ static void must_fail(void* arg, grpc_error_handle error) { /* connect to a broken address */ GRPC_CLOSURE_INIT(&done, must_fail, nullptr, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect(&done, &g_connecting, grpc_slice_allocator_create_unlimited(), nullptr, - nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args* args = grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_tcp_client_connect(&done, &g_connecting, nullptr, args, &resolved_addr, + GRPC_MILLIS_INF_FUTURE); + grpc_channel_args_destroy(args); grpc_core::ExecCtx::Get()->Flush(); diff --git a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm index ea7d00d69b6..1db7ffa8e25 100644 --- a/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm +++ b/test/core/iomgr/ios/CFStreamTests/CFStreamEndpointTests.mm @@ -24,13 +24,14 @@ #include +#include #include #include #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_client.h" -#include "test/core/util/resource_user_util.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/test_config.h" static const int kConnectTimeout = 5; @@ -126,8 +127,9 @@ static bool compare_slice_buffer_with_buffer(grpc_slice_buffer *slices, const ch /* connect to it */ XCTAssertEqual(getsockname(svr_fd, (struct sockaddr *)addr, (socklen_t *)&resolved_addr.len), 0); init_event_closure(&done, &connected); - grpc_tcp_client_connect(&done, &ep_, grpc_slice_allocator_create_unlimited(), nullptr, nullptr, - &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args *args = grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_tcp_client_connect(&done, &ep_, nullptr, args, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args_destroy(args); /* await the connection */ do { diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc deleted file mode 100644 index 959542d3e3a..00000000000 --- a/test/core/iomgr/resource_quota_test.cc +++ /dev/null @@ -1,1027 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "src/core/lib/iomgr/resource_quota.h" - -#include -#include - -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/slice/slice_internal.h" -#include "test/core/util/test_config.h" - -gpr_mu g_mu; -gpr_cv g_cv; - -static void inc_int_cb(void* a, grpc_error_handle /*error*/) { - gpr_mu_lock(&g_mu); - ++*static_cast(a); - gpr_cv_signal(&g_cv); - gpr_mu_unlock(&g_mu); -} - -static void assert_counter_becomes(int* ctr, int value) { - gpr_mu_lock(&g_mu); - gpr_timespec deadline = grpc_timeout_seconds_to_deadline(5); - while (*ctr != value) { - GPR_ASSERT(!gpr_cv_wait(&g_cv, &g_mu, deadline)); - } - gpr_mu_unlock(&g_mu); -} - -static void set_event_cb(void* a, grpc_error_handle /*error*/) { - gpr_event_set(static_cast(a), reinterpret_cast(1)); -} -grpc_closure* set_event(gpr_event* ev) { - return GRPC_CLOSURE_CREATE(set_event_cb, ev, grpc_schedule_on_exec_ctx); -} - -typedef struct { - size_t size; - grpc_resource_user* resource_user; - grpc_closure* then; -} reclaimer_args; - -static void reclaimer_cb(void* args, grpc_error_handle error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); - reclaimer_args* a = static_cast(args); - grpc_resource_user_free(a->resource_user, a->size); - grpc_resource_user_finish_reclamation(a->resource_user); - grpc_core::Closure::Run(DEBUG_LOCATION, a->then, GRPC_ERROR_NONE); - gpr_free(a); -} - -grpc_closure* make_reclaimer(grpc_resource_user* resource_user, size_t size, - grpc_closure* then) { - reclaimer_args* a = static_cast(gpr_malloc(sizeof(*a))); - a->size = size; - a->resource_user = resource_user; - a->then = then; - return GRPC_CLOSURE_CREATE(reclaimer_cb, a, grpc_schedule_on_exec_ctx); -} - -static void unused_reclaimer_cb(void* arg, grpc_error_handle error) { - GPR_ASSERT(error == GRPC_ERROR_CANCELLED); - grpc_core::Closure::Run(DEBUG_LOCATION, static_cast(arg), - GRPC_ERROR_NONE); -} -grpc_closure* make_unused_reclaimer(grpc_closure* then) { - return GRPC_CLOSURE_CREATE(unused_reclaimer_cb, then, - grpc_schedule_on_exec_ctx); -} - -static void destroy_user(grpc_resource_user* usr) { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_unref(usr); -} - -static void test_no_op(void) { - gpr_log(GPR_INFO, "** test_no_op **"); - grpc_resource_quota_unref(grpc_resource_quota_create("test_no_op")); -} - -static void test_resize_then_destroy(void) { - gpr_log(GPR_INFO, "** test_resize_then_destroy **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_resize_then_destroy"); - grpc_resource_quota_resize(q, 1024 * 1024); - grpc_resource_quota_unref(q); -} - -static void test_resource_user_no_op(void) { - gpr_log(GPR_INFO, "** test_resource_user_no_op **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_resource_user_no_op"); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_instant_alloc_then_free(void) { - gpr_log(GPR_INFO, "** test_instant_alloc_then_free **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_instant_alloc_then_free"); - grpc_resource_quota_resize(q, 1024 * 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr)); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_instant_alloc_free_pair(void) { - gpr_log(GPR_INFO, "** test_instant_alloc_free_pair **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_instant_alloc_free_pair"); - grpc_resource_quota_resize(q, 1024 * 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr)); - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_simple_async_alloc(void) { - gpr_log(GPR_INFO, "** test_simple_async_alloc **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_simple_async_alloc"); - grpc_resource_quota_resize(q, 1024 * 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - { - // Now the allocation should be inline. - GPR_ASSERT(grpc_resource_user_alloc(usr, 1024, nullptr)); - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_async_alloc_blocked_by_size(void) { - gpr_log(GPR_INFO, "** test_async_alloc_blocked_by_size **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_async_alloc_blocked_by_size"); - grpc_resource_quota_resize(q, 1); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - gpr_event ev; - gpr_event_init(&ev); - { - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait( - &ev, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); - } - grpc_resource_quota_resize(q, 1024); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_scavenge(void) { - gpr_log(GPR_INFO, "** test_scavenge **"); - grpc_resource_quota* q = grpc_resource_quota_create("test_scavenge"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr1 = grpc_resource_user_create(q, "usr1"); - grpc_resource_user* usr2 = grpc_resource_user_create(q, "usr2"); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr1, 1024); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr2, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr1); - destroy_user(usr2); -} - -static void test_scavenge_blocked(void) { - gpr_log(GPR_INFO, "** test_scavenge_blocked **"); - grpc_resource_quota* q = grpc_resource_quota_create("test_scavenge_blocked"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr1 = grpc_resource_user_create(q, "usr1"); - grpc_resource_user* usr2 = grpc_resource_user_create(q, "usr2"); - gpr_event ev; - { - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait( - &ev, grpc_timeout_milliseconds_to_deadline(100)) == nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr1, 1024); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr2, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr1); - destroy_user(usr2); -} - -static void test_blocked_until_scheduled_reclaim(void) { - gpr_log(GPR_INFO, "** test_blocked_until_scheduled_reclaim **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_blocked_until_scheduled_reclaim"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - gpr_event reclaim_done; - gpr_event_init(&reclaim_done); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_reclaimer(usr, 1024, set_event(&reclaim_done))); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaim_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_blocked_until_scheduled_reclaim_and_scavenge(void) { - gpr_log(GPR_INFO, "** test_blocked_until_scheduled_reclaim_and_scavenge **"); - grpc_resource_quota* q = grpc_resource_quota_create( - "test_blocked_until_scheduled_reclaim_and_scavenge"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr1 = grpc_resource_user_create(q, "usr1"); - grpc_resource_user* usr2 = grpc_resource_user_create(q, "usr2"); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr1, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - gpr_event reclaim_done; - gpr_event_init(&reclaim_done); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr1, false, make_reclaimer(usr1, 1024, set_event(&reclaim_done))); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr2, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaim_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr2, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr1); - destroy_user(usr2); -} - -static void test_blocked_until_scheduled_destructive_reclaim(void) { - gpr_log(GPR_INFO, "** test_blocked_until_scheduled_destructive_reclaim **"); - grpc_resource_quota* q = grpc_resource_quota_create( - "test_blocked_until_scheduled_destructive_reclaim"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - gpr_event reclaim_done; - gpr_event_init(&reclaim_done); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, true, make_reclaimer(usr, 1024, set_event(&reclaim_done))); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaim_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); -} - -static void test_unused_reclaim_is_cancelled(void) { - gpr_log(GPR_INFO, "** test_unused_reclaim_is_cancelled **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_unused_reclaim_is_cancelled"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - gpr_event benign_done; - gpr_event_init(&benign_done); - gpr_event destructive_done; - gpr_event_init(&destructive_done); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_unused_reclaimer(set_event(&benign_done))); - grpc_resource_user_post_reclaimer( - usr, true, make_unused_reclaimer(set_event(&destructive_done))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - grpc_resource_quota_unref(q); - destroy_user(usr); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); -} - -static void test_benign_reclaim_is_preferred(void) { - gpr_log(GPR_INFO, "** test_benign_reclaim_is_preferred **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_benign_reclaim_is_preferred"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - gpr_event benign_done; - gpr_event_init(&benign_done); - gpr_event destructive_done; - gpr_event_init(&destructive_done); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_reclaimer(usr, 1024, set_event(&benign_done))); - grpc_resource_user_post_reclaimer( - usr, true, make_unused_reclaimer(set_event(&destructive_done))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); -} - -static void test_multiple_reclaims_can_be_triggered(void) { - gpr_log(GPR_INFO, "** test_multiple_reclaims_can_be_triggered **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_multiple_reclaims_can_be_triggered"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - gpr_event benign_done; - gpr_event_init(&benign_done); - gpr_event destructive_done; - gpr_event_init(&destructive_done); - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_reclaimer(usr, 512, set_event(&benign_done))); - grpc_resource_user_post_reclaimer( - usr, true, make_reclaimer(usr, 512, set_event(&destructive_done))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - gpr_event ev; - gpr_event_init(&ev); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&ev))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(5)) != - nullptr); - ; - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - grpc_resource_quota_unref(q); - destroy_user(usr); - GPR_ASSERT(gpr_event_wait(&benign_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&destructive_done, - grpc_timeout_seconds_to_deadline(5)) != nullptr); -} - -static void test_resource_user_stays_allocated_until_memory_released(void) { - gpr_log(GPR_INFO, - "** test_resource_user_stays_allocated_until_memory_released **"); - grpc_resource_quota* q = grpc_resource_quota_create( - "test_resource_user_stays_allocated_until_memory_released"); - grpc_resource_quota_resize(q, 1024 * 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, nullptr)); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_quota_unref(q); - grpc_resource_user_unref(usr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } -} - -static void -test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released( - void) { - gpr_log(GPR_INFO, - "** " - "test_resource_user_stays_allocated_and_reclaimers_unrun_until_" - "memory_released **"); - grpc_resource_quota* q = grpc_resource_quota_create( - "test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_" - "released"); - grpc_resource_quota_resize(q, 1024); - for (int i = 0; i < 10; i++) { - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - gpr_event reclaimer_cancelled; - gpr_event_init(&reclaimer_cancelled); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_unused_reclaimer(set_event(&reclaimer_cancelled))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaimer_cancelled, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - gpr_event allocated; - gpr_event_init(&allocated); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline( - 5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&reclaimer_cancelled, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_unref(usr); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaimer_cancelled, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaimer_cancelled, - grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - } - grpc_resource_quota_unref(q); -} - -static void test_reclaimers_can_be_posted_repeatedly(void) { - gpr_log(GPR_INFO, "** test_reclaimers_can_be_posted_repeatedly **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_reclaimers_can_be_posted_repeatedly"); - grpc_resource_quota_resize(q, 1024); - grpc_resource_user* usr = grpc_resource_user_create(q, "usr"); - { - gpr_event allocated; - gpr_event_init(&allocated); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&allocated, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - } - for (int i = 0; i < 10; i++) { - gpr_event reclaimer_done; - gpr_event_init(&reclaimer_done); - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_post_reclaimer( - usr, false, make_reclaimer(usr, 1024, set_event(&reclaimer_done))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&reclaimer_done, - grpc_timeout_milliseconds_to_deadline(100)) == - nullptr); - } - { - gpr_event allocated; - gpr_event_init(&allocated); - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_resource_user_alloc(usr, 1024, set_event(&allocated))); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&allocated, grpc_timeout_seconds_to_deadline( - 5)) != nullptr); - GPR_ASSERT(gpr_event_wait(&reclaimer_done, - grpc_timeout_seconds_to_deadline(5)) != - nullptr); - } - } - { - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_free(usr, 1024); - } - destroy_user(usr); - grpc_resource_quota_unref(q); -} - -static void test_one_slice(void) { - gpr_log(GPR_INFO, "** test_one_slice **"); - grpc_resource_quota* q = grpc_resource_quota_create("test_one_slice"); - grpc_resource_quota_resize(q, 1024); - grpc_slice_allocator* alloc = grpc_slice_allocator_create(q, "usr"); - int num_allocs = 0; - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - { - const int start_allocs = num_allocs; - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - alloc, 1024, 1, grpc_slice_allocator_intent::kDefault, &buffer, - inc_int_cb, &num_allocs)); - grpc_core::ExecCtx::Get()->Flush(); - assert_counter_becomes(&num_allocs, start_allocs + 1); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_buffer_destroy_internal(&buffer); - grpc_slice_allocator_destroy(alloc); - } - grpc_resource_quota_unref(q); -} - -static void test_one_slice_through_slice_allocator_factory(void) { - gpr_log(GPR_INFO, "** test_one_slice_through_slice_allocator_factory **"); - grpc_resource_quota* resource_quota = grpc_resource_quota_create( - "test_one_slice_through_slice_allocator_factory"); - int num_allocs = 0; - grpc_resource_quota_resize(resource_quota, 1024); - grpc_slice_allocator_factory* slice_allocator_factory = - grpc_slice_allocator_factory_create(resource_quota); - grpc_slice_allocator* slice_allocator = - grpc_slice_allocator_factory_create_slice_allocator( - slice_allocator_factory, "usr"); - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - { - const int start_allocs = num_allocs; - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - slice_allocator, 1024, 1, grpc_slice_allocator_intent::kDefault, - &buffer, inc_int_cb, &num_allocs)); - grpc_core::ExecCtx::Get()->Flush(); - assert_counter_becomes(&num_allocs, start_allocs + 1); - } - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_buffer_destroy_internal(&buffer); - grpc_slice_allocator_destroy(slice_allocator); - grpc_slice_allocator_factory_destroy(slice_allocator_factory); - } -} - -static void test_slice_allocator_pressure_adjusted_allocation() { - gpr_log(GPR_INFO, "** test_slice_allocator_pressure_adjusted_allocation **"); - // Quota large enough to avoid the 1/16 maximum allocation limit. - grpc_resource_quota* resource_quota = grpc_resource_quota_create( - "test_one_slice_through_slice_allocator_factory"); - grpc_resource_quota_resize(resource_quota, 32 * 1024); - grpc_resource_user* black_hole_resource_user = - grpc_resource_user_create(resource_quota, "black hole"); - { - // Consume ~95% of the quota - grpc_core::ExecCtx exec_ctx; - grpc_resource_user_safe_alloc(black_hole_resource_user, 31 * 1024); - } - GPR_ASSERT(grpc_resource_quota_get_memory_pressure(resource_quota) > 0.95); - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - grpc_slice_allocator* constrained_allocator = - grpc_slice_allocator_create(resource_quota, "constrained user"); - { - // Attempt to get 512 bytes - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - constrained_allocator, 2 * 1024, 1, - grpc_slice_allocator_intent::kReadBuffer, &buffer, - [](void*, grpc_error_handle) {}, nullptr)); - } - grpc_slice slice = grpc_slice_buffer_take_first(&buffer); - GPR_ASSERT(grpc_refcounted_slice_length(slice) < 2 * 1024); - GPR_ASSERT(grpc_refcounted_slice_length(slice) >= 256); - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_unref(slice); - grpc_resource_user_free(black_hole_resource_user, 31 * 1024); - grpc_resource_user_unref(black_hole_resource_user); - grpc_slice_allocator_destroy(constrained_allocator); - grpc_resource_quota_unref(resource_quota); - grpc_slice_buffer_destroy_internal(&buffer); - } -} - -static void test_slice_allocator_capped_allocation() { - gpr_log(GPR_INFO, "** test_slice_allocator_pressure_adjusted_allocation **"); - grpc_resource_quota* resource_quota = grpc_resource_quota_create( - "test_one_slice_through_slice_allocator_factory"); - grpc_resource_quota_resize(resource_quota, 32 * 1024); - grpc_arg to_add[2]; - grpc_channel_args* ch_args; - to_add[0] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_TCP_MIN_READ_CHUNK_SIZE), 1024); - to_add[1] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_TCP_MAX_READ_CHUNK_SIZE), 2048); - ch_args = grpc_channel_args_copy_and_add(nullptr, to_add, 2); - grpc_slice_allocator* slice_allocator = - grpc_slice_allocator_create(resource_quota, "capped user", ch_args); - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - { - // Attempt to get more than the maximum - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - slice_allocator, 4 * 1024, 1, grpc_slice_allocator_intent::kReadBuffer, - &buffer, [](void*, grpc_error_handle) {}, nullptr)); - } - grpc_slice max_slice = grpc_slice_buffer_take_first(&buffer); - GPR_ASSERT(grpc_refcounted_slice_length(max_slice) == 2048); - { - // Attempt to get less than the minimum - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - slice_allocator, 512, 1, grpc_slice_allocator_intent::kReadBuffer, - &buffer, [](void*, grpc_error_handle) {}, nullptr)); - } - grpc_slice min_slice = grpc_slice_buffer_take_first(&buffer); - GPR_ASSERT(grpc_refcounted_slice_length(min_slice) == 1024); - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_unref(max_slice); - grpc_slice_unref(min_slice); - grpc_slice_allocator_destroy(slice_allocator); - grpc_resource_quota_unref(resource_quota); - grpc_slice_buffer_destroy_internal(&buffer); - grpc_channel_args_destroy(ch_args); - } -} - -static void test_one_slice_deleted_late(void) { - gpr_log(GPR_INFO, "** test_one_slice_deleted_late **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_one_slice_deleted_late"); - grpc_resource_quota_resize(q, 1024); - grpc_slice_allocator* alloc = grpc_slice_allocator_create(q, "usr"); - int num_allocs = 0; - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - { - const int start_allocs = num_allocs; - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - alloc, 1024, 1, grpc_slice_allocator_intent::kDefault, &buffer, - inc_int_cb, &num_allocs)); - grpc_core::ExecCtx::Get()->Flush(); - assert_counter_becomes(&num_allocs, start_allocs + 1); - } - - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_allocator_destroy(alloc); - grpc_resource_quota_unref(q); - grpc_slice_buffer_destroy_internal(&buffer); - } -} - -static void test_resize_to_zero(void) { - gpr_log(GPR_INFO, "** test_resize_to_zero **"); - grpc_resource_quota* q = grpc_resource_quota_create("test_resize_to_zero"); - grpc_resource_quota_resize(q, 0); - grpc_resource_quota_unref(q); -} - -static void test_negative_rq_free_pool(void) { - gpr_log(GPR_INFO, "** test_negative_rq_free_pool **"); - grpc_resource_quota* q = - grpc_resource_quota_create("test_negative_rq_free_pool"); - grpc_resource_quota_resize(q, 1024); - grpc_slice_allocator* alloc = grpc_slice_allocator_create(q, "usr"); - int num_allocs = 0; - grpc_slice_buffer buffer; - grpc_slice_buffer_init(&buffer); - - { - const int start_allocs = num_allocs; - grpc_core::ExecCtx exec_ctx; - GPR_ASSERT(!grpc_slice_allocator_allocate( - alloc, 1024, 1, grpc_slice_allocator_intent::kDefault, &buffer, - inc_int_cb, &num_allocs)); - grpc_core::ExecCtx::Get()->Flush(); - assert_counter_becomes(&num_allocs, start_allocs + 1); - } - - grpc_resource_quota_resize(q, 512); - - double eps = 0.0001; - GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) < 1 + eps); - GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) > 1 - eps); - - { - grpc_core::ExecCtx exec_ctx; - grpc_slice_allocator_destroy(alloc); - grpc_resource_quota_unref(q); - grpc_slice_buffer_destroy_internal(&buffer); - } -} - -// Simple test to check resource quota thread limits -static void test_thread_limit() { - grpc_core::ExecCtx exec_ctx; - - grpc_resource_quota* rq = grpc_resource_quota_create("test_thread_limit"); - grpc_resource_user* ru1 = grpc_resource_user_create(rq, "ru1"); - grpc_resource_user* ru2 = grpc_resource_user_create(rq, "ru2"); - - // Max threads = 100 - grpc_resource_quota_set_max_threads(rq, 100); - - // Request quota for 100 threads (50 for ru1, 50 for ru2) - GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 10)); - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 10)); - GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 40)); - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 40)); - - // Threads exhausted. Next request must fail - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru2, 20)); - - // Free 20 threads from two different users - grpc_resource_user_free_threads(ru1, 10); - grpc_resource_user_free_threads(ru2, 10); - - // Next request to 20 threads must succeed - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 20)); - - // No more thread quota again - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 20)); - - // Free 10 more - grpc_resource_user_free_threads(ru1, 10); - - GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 5)); - GPR_ASSERT( - !grpc_resource_user_allocate_threads(ru2, 10)); // Only 5 available - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 5)); - - // Teardown (ru1 and ru2 release all the quota back to rq) - grpc_resource_user_unref(ru1); - grpc_resource_user_unref(ru2); - grpc_resource_quota_unref(rq); -} - -// Change max quota in either direction dynamically -static void test_thread_maxquota_change() { - grpc_core::ExecCtx exec_ctx; - - grpc_resource_quota* rq = - grpc_resource_quota_create("test_thread_maxquota_change"); - grpc_resource_user* ru1 = grpc_resource_user_create(rq, "ru1"); - grpc_resource_user* ru2 = grpc_resource_user_create(rq, "ru2"); - - // Max threads = 100 - grpc_resource_quota_set_max_threads(rq, 100); - - // Request quota for 100 threads (50 for ru1, 50 for ru2) - GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 50)); - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 50)); - - // Threads exhausted. Next request must fail - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru2, 20)); - - // Increase maxquota and retry - // Max threads = 150; - grpc_resource_quota_set_max_threads(rq, 150); - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 20)); // ru2=70, ru1=50 - - // Decrease maxquota (Note: Quota already given to ru1 and ru2 is - // unaffected) Max threads = 10; - grpc_resource_quota_set_max_threads(rq, 10); - - // New requests will fail until quota is available - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); - - // Make quota available - grpc_resource_user_free_threads(ru1, 50); // ru1 now has 0 - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); // not enough - - grpc_resource_user_free_threads(ru2, 70); // ru2 now has 0 - - // Now we can get quota up-to 10, the current max - GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 10)); - // No more thread quota again - GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); - - // Teardown (ru1 and ru2 release all the quota back to rq) - grpc_resource_user_unref(ru1); - grpc_resource_user_unref(ru2); - grpc_resource_quota_unref(rq); -} - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - grpc_init(); - gpr_mu_init(&g_mu); - gpr_cv_init(&g_cv); - test_no_op(); - test_resize_then_destroy(); - test_resource_user_no_op(); - test_instant_alloc_then_free(); - test_instant_alloc_free_pair(); - test_simple_async_alloc(); - test_async_alloc_blocked_by_size(); - test_scavenge(); - test_scavenge_blocked(); - test_blocked_until_scheduled_reclaim(); - test_blocked_until_scheduled_reclaim_and_scavenge(); - test_blocked_until_scheduled_destructive_reclaim(); - test_unused_reclaim_is_cancelled(); - test_benign_reclaim_is_preferred(); - test_multiple_reclaims_can_be_triggered(); - test_resource_user_stays_allocated_until_memory_released(); - test_resource_user_stays_allocated_and_reclaimers_unrun_until_memory_released(); - test_reclaimers_can_be_posted_repeatedly(); - test_one_slice(); - test_one_slice_deleted_late(); - test_resize_to_zero(); - test_negative_rq_free_pool(); - test_one_slice_through_slice_allocator_factory(); - test_slice_allocator_pressure_adjusted_allocation(); - test_slice_allocator_capped_allocation(); - gpr_mu_destroy(&g_mu); - gpr_cv_destroy(&g_cv); - - // Resource quota thread related - test_thread_limit(); - test_thread_maxquota_change(); - - grpc_shutdown(); - return 0; -} diff --git a/test/core/iomgr/tcp_client_posix_test.cc b/test/core/iomgr/tcp_client_posix_test.cc index e5ec7bc3544..3124ca5edb3 100644 --- a/test/core/iomgr/tcp_client_posix_test.cc +++ b/test/core/iomgr/tcp_client_posix_test.cc @@ -37,7 +37,7 @@ #include "src/core/lib/iomgr/socket_utils_posix.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/iomgr/timer.h" -#include "test/core/util/resource_user_util.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/test_config.h" static grpc_pollset_set* g_pollset_set; @@ -106,9 +106,11 @@ void test_succeeds(void) { GPR_ASSERT(getsockname(svr_fd, (struct sockaddr*)addr, (socklen_t*)&resolved_addr.len) == 0); GRPC_CLOSURE_INIT(&done, must_succeed, nullptr, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect( - &done, &g_connecting, grpc_slice_allocator_create_unlimited(), - g_pollset_set, nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_tcp_client_connect(&done, &g_connecting, g_pollset_set, args, + &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_channel_args_destroy(args); /* await the connection */ do { resolved_addr.len = static_cast(sizeof(addr)); @@ -155,9 +157,8 @@ void test_fails(void) { /* connect to a broken address */ GRPC_CLOSURE_INIT(&done, must_fail, nullptr, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect( - &done, &g_connecting, grpc_slice_allocator_create_unlimited(), - g_pollset_set, nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_tcp_client_connect(&done, &g_connecting, g_pollset_set, nullptr, + &resolved_addr, GRPC_MILLIS_INF_FUTURE); gpr_mu_lock(g_mu); /* wait for the connection callback to finish */ @@ -202,9 +203,8 @@ void test_fails_bad_addr_no_leak(void) { gpr_mu_unlock(g_mu); // connect to an invalid address. GRPC_CLOSURE_INIT(&done, must_fail, nullptr, grpc_schedule_on_exec_ctx); - grpc_tcp_client_connect( - &done, &g_connecting, grpc_slice_allocator_create_unlimited(), - g_pollset_set, nullptr, &resolved_addr, GRPC_MILLIS_INF_FUTURE); + grpc_tcp_client_connect(&done, &g_connecting, g_pollset_set, nullptr, + &resolved_addr, GRPC_MILLIS_INF_FUTURE); gpr_mu_lock(g_mu); while (g_connections_complete == connections_complete_before) { grpc_pollset_worker* worker = nullptr; diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 4d7e371e892..507e0045449 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -40,7 +40,6 @@ #include "src/core/lib/iomgr/tcp_posix.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/iomgr/endpoint_tests.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" static gpr_mu* g_mu; @@ -213,13 +212,17 @@ static void read_test(size_t num_bytes, size_t slice_size) { create_sockets(sv); - grpc_arg a[1]; + grpc_arg a[2]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = static_cast(slice_size); + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test", false), &args, "test", - grpc_slice_allocator_create_unlimited()); + ep = + grpc_tcp_create(grpc_fd_create(sv[1], "read_test", false), &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); written_bytes = fill_socket_partial(sv[0], num_bytes); @@ -247,6 +250,8 @@ static void read_test(size_t num_bytes, size_t slice_size) { grpc_slice_buffer_destroy_internal(&state.incoming); grpc_endpoint_destroy(ep); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); } /* Write to a socket until it fills up, then read from it using the grpc_tcp @@ -264,13 +269,17 @@ static void large_read_test(size_t slice_size) { create_sockets(sv); - grpc_arg a[1]; + grpc_arg a[2]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; a[0].value.integer = static_cast(slice_size); + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "large_read_test", false), &args, - "test", grpc_slice_allocator_create_unlimited()); + "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); written_bytes = fill_socket(sv[0]); @@ -298,6 +307,8 @@ static void large_read_test(size_t slice_size) { grpc_slice_buffer_destroy_internal(&state.incoming); grpc_endpoint_destroy(ep); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); } struct write_socket_state { @@ -425,13 +436,17 @@ static void write_test(size_t num_bytes, size_t slice_size, create_sockets(sv); } - grpc_arg a[1]; + grpc_arg a[2]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = static_cast(slice_size); + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", collect_timestamps), - &args, "test", grpc_slice_allocator_create_unlimited()); + &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); state.ep = ep; @@ -471,6 +486,8 @@ static void write_test(size_t num_bytes, size_t slice_size, grpc_slice_buffer_destroy_internal(&outgoing); grpc_endpoint_destroy(ep); gpr_free(slices); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); } void on_fd_released(void* arg, grpc_error_handle /*errors*/) { @@ -502,13 +519,17 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { create_sockets(sv); - grpc_arg a[1]; + grpc_arg a[2]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; a[0].value.integer = static_cast(slice_size); + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - ep = grpc_tcp_create(grpc_fd_create(sv[1], "read_test", false), &args, "test", - grpc_slice_allocator_create_unlimited()); + ep = + grpc_tcp_create(grpc_fd_create(sv[1], "read_test", false), &args, "test"); GPR_ASSERT(grpc_tcp_fd(ep) == sv[1] && sv[1] >= 0); grpc_endpoint_add_to_pollset(ep, g_pollset); @@ -556,6 +577,8 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { written_bytes = fill_socket_partial(fd, num_bytes); drain_socket_blocking(sv[0], written_bytes, written_bytes); close(fd); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); } void run_tests(void) { @@ -597,19 +620,23 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair( grpc_core::ExecCtx exec_ctx; create_sockets(sv); - grpc_arg a[1]; + grpc_arg a[2]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER; a[0].value.integer = static_cast(slice_size); + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - f.client_ep = - grpc_tcp_create(grpc_fd_create(sv[0], "fixture:client", false), &args, - "test", grpc_slice_allocator_create_unlimited()); - f.server_ep = - grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server", false), &args, - "test", grpc_slice_allocator_create_unlimited()); + f.client_ep = grpc_tcp_create(grpc_fd_create(sv[0], "fixture:client", false), + &args, "test"); + f.server_ep = grpc_tcp_create(grpc_fd_create(sv[1], "fixture:server", false), + &args, "test"); grpc_endpoint_add_to_pollset(f.client_ep, g_pollset); grpc_endpoint_add_to_pollset(f.server_ep, g_pollset); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); return f; } diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc index f83a3704978..c9e09183020 100644 --- a/test/core/iomgr/tcp_server_posix_test.cc +++ b/test/core/iomgr/tcp_server_posix_test.cc @@ -44,6 +44,7 @@ #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -163,22 +164,20 @@ static void on_connect(void* /*arg*/, grpc_endpoint* tcp, static void test_no_op(void) { grpc_core::ExecCtx exec_ctx; grpc_tcp_server* s; - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_tcp_server_create(nullptr, nullptr, - grpc_slice_allocator_factory_create( - grpc_resource_quota_create(nullptr)), - &s)); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s)); + grpc_channel_args_destroy(args); grpc_tcp_server_unref(s); } static void test_no_op_with_start(void) { grpc_core::ExecCtx exec_ctx; grpc_tcp_server* s; - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_tcp_server_create(nullptr, nullptr, - grpc_slice_allocator_factory_create( - grpc_resource_quota_create(nullptr)), - &s)); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s)); + grpc_channel_args_destroy(args); LOG_TEST("test_no_op_with_start"); std::vector empty_pollset; grpc_tcp_server_start(s, &empty_pollset, on_connect, nullptr); @@ -191,11 +190,10 @@ static void test_no_op_with_port(void) { struct sockaddr_in* addr = reinterpret_cast(resolved_addr.addr); grpc_tcp_server* s; - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_tcp_server_create(nullptr, nullptr, - grpc_slice_allocator_factory_create( - grpc_resource_quota_create(nullptr)), - &s)); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s)); + grpc_channel_args_destroy(args); LOG_TEST("test_no_op_with_port"); memset(&resolved_addr, 0, sizeof(resolved_addr)); @@ -215,11 +213,10 @@ static void test_no_op_with_port_and_start(void) { struct sockaddr_in* addr = reinterpret_cast(resolved_addr.addr); grpc_tcp_server* s; - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_tcp_server_create(nullptr, nullptr, - grpc_slice_allocator_factory_create( - grpc_resource_quota_create(nullptr)), - &s)); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(nullptr, args, &s)); + grpc_channel_args_destroy(args); LOG_TEST("test_no_op_with_port_and_start"); int port = -1; @@ -315,12 +312,11 @@ static void test_connect(size_t num_connects, int svr1_port; grpc_tcp_server* s; const unsigned num_ports = 2; + grpc_channel_args* new_channel_args = + grpc_core::EnsureResourceQuotaInChannelArgs(channel_args); GPR_ASSERT(GRPC_ERROR_NONE == - grpc_tcp_server_create( - nullptr, channel_args, - grpc_slice_allocator_factory_create( - grpc_resource_quota_from_channel_args(channel_args, true)), - &s)); + grpc_tcp_server_create(nullptr, new_channel_args, &s)); + grpc_channel_args_destroy(new_channel_args); unsigned port_num; server_weak_ref weak_ref; server_weak_ref_init(&weak_ref); diff --git a/test/core/resource_quota/memory_quota_fuzzer.cc b/test/core/resource_quota/memory_quota_fuzzer.cc index b3326f52148..26d0ecc4082 100644 --- a/test/core/resource_quota/memory_quota_fuzzer.cc +++ b/test/core/resource_quota/memory_quota_fuzzer.cc @@ -63,15 +63,17 @@ class Fuzzer { ExecCtx::Get()->Flush(); break; case memory_quota_fuzzer::Action::kCreateQuota: - memory_quotas_.emplace(action.quota(), MemoryQuota()); + memory_quotas_.emplace(action.quota(), + MemoryQuota(absl::StrCat("quota-step-", i))); break; case memory_quota_fuzzer::Action::kDeleteQuota: memory_quotas_.erase(action.quota()); break; case memory_quota_fuzzer::Action::kCreateAllocator: - WithQuota(action.quota(), [this, action](MemoryQuota* q) { - memory_allocators_.emplace(action.allocator(), - q->CreateMemoryOwner()); + WithQuota(action.quota(), [this, action, i](MemoryQuota* q) { + memory_allocators_.emplace( + action.allocator(), + q->CreateMemoryOwner(absl::StrCat("allocator-step-", i))); }); break; case memory_quota_fuzzer::Action::kDeleteAllocator: @@ -97,7 +99,7 @@ class Fuzzer { MemoryRequest req(min, max); WithAllocator( action.allocator(), [this, action, req](MemoryOwner* a) { - auto alloc = a->allocator()->MakeReservation(req); + auto alloc = a->MakeReservation(req); allocations_.emplace(action.allocation(), std::move(alloc)); }); } break; diff --git a/test/core/resource_quota/memory_quota_stress_test.cc b/test/core/resource_quota/memory_quota_stress_test.cc index 7929792eeca..0c8b3075091 100644 --- a/test/core/resource_quota/memory_quota_stress_test.cc +++ b/test/core/resource_quota/memory_quota_stress_test.cc @@ -26,12 +26,13 @@ class StressTest { // Create a stress test with some size. StressTest(size_t num_quotas, size_t num_allocators) { for (size_t i = 0; i < num_quotas; ++i) { - quotas_.emplace_back(); + quotas_.emplace_back(absl::StrCat("quota[", i, "]")); } std::random_device g; std::uniform_int_distribution dist(0, num_quotas - 1); for (size_t i = 0; i < num_allocators; ++i) { - allocators_.emplace_back(quotas_[dist(g)].CreateMemoryOwner()); + allocators_.emplace_back(quotas_[dist(g)].CreateMemoryOwner( + absl::StrCat("allocator[", i, "]"))); } } @@ -54,8 +55,8 @@ class StressTest { {ReclamationPass::kBenign, ReclamationPass::kIdle, ReclamationPass::kDestructive}) { threads.push_back(Run([allocator, pass](StatePtr st) mutable { - if (st->RememberReservation(allocator->allocator()->MakeReservation( - st->RandomRequest()))) { + if (st->RememberReservation( + allocator->MakeReservation(st->RandomRequest()))) { allocator->PostReclaimer( pass, [st](absl::optional sweep) { if (!sweep.has_value()) return; diff --git a/test/core/resource_quota/memory_quota_test.cc b/test/core/resource_quota/memory_quota_test.cc index c1e9985acd0..31e7346f35f 100644 --- a/test/core/resource_quota/memory_quota_test.cc +++ b/test/core/resource_quota/memory_quota_test.cc @@ -55,26 +55,26 @@ TEST(MemoryRequestTest, MinMax) { // MemoryQuotaTest // -TEST(MemoryQuotaTest, NoOp) { MemoryQuota(); } +TEST(MemoryQuotaTest, NoOp) { MemoryQuota("foo"); } TEST(MemoryQuotaTest, CreateAllocatorNoOp) { - MemoryQuota memory_quota; - auto memory_allocator = memory_quota.CreateMemoryAllocator(); + MemoryQuota memory_quota("foo"); + auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); } TEST(MemoryQuotaTest, CreateObjectFromAllocator) { - MemoryQuota memory_quota; - auto memory_allocator = memory_quota.CreateMemoryAllocator(); + MemoryQuota memory_quota("foo"); + auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); auto object = memory_allocator.MakeUnique>(); } TEST(MemoryQuotaTest, CreateSomeObjectsAndExpectReclamation) { ExecCtx exec_ctx; - MemoryQuota memory_quota; + MemoryQuota memory_quota("foo"); memory_quota.SetSize(4096); - auto memory_allocator = memory_quota.CreateMemoryOwner(); - auto object = memory_allocator.allocator()->MakeUnique>(); + auto memory_allocator = memory_quota.CreateMemoryOwner("bar"); + auto object = memory_allocator.MakeUnique>(); auto checker1 = CallChecker::Make(); memory_allocator.PostReclaimer( @@ -84,7 +84,7 @@ TEST(MemoryQuotaTest, CreateSomeObjectsAndExpectReclamation) { EXPECT_TRUE(sweep.has_value()); object.reset(); }); - auto object2 = memory_allocator.allocator()->MakeUnique>(); + auto object2 = memory_allocator.MakeUnique>(); exec_ctx.Flush(); EXPECT_EQ(object.get(), nullptr); @@ -96,7 +96,7 @@ TEST(MemoryQuotaTest, CreateSomeObjectsAndExpectReclamation) { EXPECT_TRUE(sweep.has_value()); object2.reset(); }); - auto object3 = memory_allocator.allocator()->MakeUnique>(); + auto object3 = memory_allocator.MakeUnique>(); exec_ctx.Flush(); EXPECT_EQ(object2.get(), nullptr); } @@ -104,16 +104,16 @@ TEST(MemoryQuotaTest, CreateSomeObjectsAndExpectReclamation) { TEST(MemoryQuotaTest, BasicRebind) { ExecCtx exec_ctx; - MemoryQuota memory_quota; + MemoryQuota memory_quota("foo"); memory_quota.SetSize(4096); - MemoryQuota memory_quota2; + MemoryQuota memory_quota2("foo2"); memory_quota2.SetSize(4096); - auto memory_allocator = memory_quota2.CreateMemoryOwner(); - auto object = memory_allocator.allocator()->MakeUnique>(); + auto memory_allocator = memory_quota2.CreateMemoryOwner("bar"); + auto object = memory_allocator.MakeUnique>(); memory_allocator.Rebind(&memory_quota); - auto memory_allocator2 = memory_quota2.CreateMemoryOwner(); + auto memory_allocator2 = memory_quota2.CreateMemoryOwner("bar2"); auto checker1 = CallChecker::Make(); memory_allocator2.PostReclaimer( @@ -138,14 +138,14 @@ TEST(MemoryQuotaTest, BasicRebind) { object.reset(); }); - auto object2 = memory_allocator.allocator()->MakeUnique>(); + auto object2 = memory_allocator.MakeUnique>(); exec_ctx.Flush(); EXPECT_EQ(object.get(), nullptr); } TEST(MemoryQuotaTest, ReserveRangeNoPressure) { - MemoryQuota memory_quota; - auto memory_allocator = memory_quota.CreateMemoryAllocator(); + MemoryQuota memory_quota("foo"); + auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); size_t total = 0; for (int i = 0; i < 10000; i++) { auto n = memory_allocator.Reserve(MemoryRequest(100, 40000)); @@ -156,8 +156,8 @@ TEST(MemoryQuotaTest, ReserveRangeNoPressure) { } TEST(MemoryQuotaTest, MakeSlice) { - MemoryQuota memory_quota; - auto memory_allocator = memory_quota.CreateMemoryAllocator(); + MemoryQuota memory_quota("foo"); + auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); std::vector slices; for (int i = 1; i < 1000; i++) { int min = i; @@ -170,8 +170,8 @@ TEST(MemoryQuotaTest, MakeSlice) { } TEST(MemoryQuotaTest, ContainerAllocator) { - MemoryQuota memory_quota; - auto memory_allocator = memory_quota.CreateMemoryAllocator(); + MemoryQuota memory_quota("foo"); + auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); Vector vec(&memory_allocator); for (int i = 0; i < 100000; i++) { vec.push_back(i); diff --git a/test/core/resource_quota/resource_quota_test.cc b/test/core/resource_quota/resource_quota_test.cc index 07852a312cf..e64bb9652b5 100644 --- a/test/core/resource_quota/resource_quota_test.cc +++ b/test/core/resource_quota/resource_quota_test.cc @@ -20,7 +20,7 @@ namespace grpc_core { namespace testing { TEST(ResourceQuotaTest, Works) { - auto q = MakeRefCounted(); + auto q = MakeRefCounted("foo"); EXPECT_NE(q->thread_quota(), nullptr); EXPECT_NE(q->memory_quota(), nullptr); } diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc index 0b3e98c0535..1e6f6d3abc9 100644 --- a/test/core/security/secure_endpoint_test.cc +++ b/test/core/security/secure_endpoint_test.cc @@ -31,7 +31,6 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/fake_transport_security.h" #include "test/core/iomgr/endpoint_tests.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" static gpr_mu* g_mu; diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 08a696cfd1d..6dc8c75fb0b 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -24,7 +24,6 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/security_connector.h" #include "test/core/util/mock_endpoint.h" -#include "test/core/util/resource_user_util.h" #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem" #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem" @@ -60,10 +59,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { { grpc_core::ExecCtx exec_ctx; - grpc_slice_allocator* slice_allocator = - grpc_slice_allocator_create_unlimited(); - grpc_endpoint* mock_endpoint = - grpc_mock_endpoint_create(discard_write, slice_allocator); + grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write); grpc_mock_endpoint_put_read( mock_endpoint, grpc_slice_from_copied_buffer((const char*)data, size)); diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc index f63ee879817..689792d2afe 100644 --- a/test/core/surface/concurrent_connectivity_test.cc +++ b/test/core/surface/concurrent_connectivity_test.cc @@ -35,6 +35,7 @@ #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -131,10 +132,10 @@ void bad_server_thread(void* vargs) { grpc_sockaddr* addr = reinterpret_cast(resolved_addr.addr); int port; grpc_tcp_server* s; - grpc_error_handle error = grpc_tcp_server_create( - nullptr, nullptr, - grpc_slice_allocator_factory_create(grpc_resource_quota_create(nullptr)), - &s); + grpc_channel_args* channel_args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_error_handle error = grpc_tcp_server_create(nullptr, channel_args, &s); + grpc_channel_args_destroy(channel_args); GPR_ASSERT(error == GRPC_ERROR_NONE); memset(&resolved_addr, 0, sizeof(resolved_addr)); addr->sa_family = GRPC_AF_INET; diff --git a/test/core/transport/binder/end2end/testing_channel_create.cc b/test/core/transport/binder/end2end/testing_channel_create.cc index bbf5732c12c..9716700d5cf 100644 --- a/test/core/transport/binder/end2end/testing_channel_create.cc +++ b/test/core/transport/binder/end2end/testing_channel_create.cc @@ -126,7 +126,7 @@ grpc_channel* grpc_binder_channel_create_for_testing(grpc_server* server, GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_channel* channel = grpc_channel_create("binder", client_args, GRPC_CLIENT_DIRECT_CHANNEL, - client_transport, nullptr, 0, &error); + client_transport, &error); GPR_ASSERT(error == GRPC_ERROR_NONE); grpc_channel_args_destroy(client_args); return channel; diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc index 89ac6ac36bd..af791b3512f 100644 --- a/test/core/transport/chttp2/context_list_test.cc +++ b/test/core/transport/chttp2/context_list_test.cc @@ -27,6 +27,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/iomgr/port.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/transport/transport.h" #include "test/core/util/mock_endpoint.h" #include "test/core/util/test_config.h" @@ -70,15 +71,11 @@ TEST_F(ContextListTest, ExecuteFlushesList) { grpc_core::ExecCtx exec_ctx; grpc_stream_refcount ref; GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "phony ref"); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("context_list_test"); - grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create( - discard_write, - grpc_slice_allocator_create(resource_quota, "mock_endpoint")); - grpc_transport* t = grpc_create_chttp2_transport( - nullptr, mock_endpoint, true, - grpc_resource_user_create(resource_quota, "mock_transport")); - grpc_resource_quota_unref(resource_quota); + grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_transport* t = grpc_create_chttp2_transport(args, mock_endpoint, true); + grpc_channel_args_destroy(args); std::vector s; s.reserve(kNumElems); gpr_atm verifier_called[kNumElems]; @@ -128,15 +125,11 @@ TEST_F(ContextListTest, NonEmptyListEmptyTimestamp) { grpc_core::ExecCtx exec_ctx; grpc_stream_refcount ref; GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "phony ref"); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("context_list_test"); - grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create( - discard_write, - grpc_slice_allocator_create(resource_quota, "mock_endpoint")); - grpc_transport* t = grpc_create_chttp2_transport( - nullptr, mock_endpoint, true, - grpc_resource_user_create(resource_quota, "mock_transport")); - grpc_resource_quota_unref(resource_quota); + grpc_endpoint* mock_endpoint = grpc_mock_endpoint_create(discard_write); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_transport* t = grpc_create_chttp2_transport(args, mock_endpoint, true); + grpc_channel_args_destroy(args); std::vector s; s.reserve(kNumElems); gpr_atm verifier_called[kNumElems]; diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index 7696d0415cd..08880db8df2 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -36,9 +36,9 @@ #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/util/port.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" namespace grpc_core { @@ -52,11 +52,15 @@ class ServerThread { void Start() { // Start server with 1-second handshake timeout. - grpc_arg arg; - arg.type = GRPC_ARG_INTEGER; - arg.key = const_cast(GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); - arg.value.integer = 1000; - grpc_channel_args args = {1, &arg}; + grpc_arg a[2]; + a[0].type = GRPC_ARG_INTEGER; + a[0].key = const_cast(GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); + a[0].value.integer = 1000; + a[1].key = const_cast(GRPC_ARG_RESOURCE_QUOTA); + a[1].type = GRPC_ARG_POINTER; + a[1].value.pointer.p = grpc_resource_quota_create("test"); + a[1].value.pointer.vtable = grpc_resource_quota_arg_vtable(); + grpc_channel_args args = {2, a}; server_ = grpc_server_create(&args, nullptr); ASSERT_TRUE(grpc_server_add_insecure_http2_port(server_, address_)); cq_ = grpc_completion_queue_create_for_next(nullptr); @@ -64,6 +68,8 @@ class ServerThread { grpc_server_start(server_); thread_ = absl::make_unique(std::bind(&ServerThread::Serve, this)); + grpc_resource_quota_unref( + static_cast(a[1].value.pointer.p)); } void Shutdown() { @@ -113,10 +119,12 @@ class Client { grpc_pollset_set* pollset_set = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(pollset_set, pollset_); EventState state; - grpc_tcp_client_connect( - state.closure(), &endpoint_, grpc_slice_allocator_create_unlimited(), - pollset_set, nullptr /* channel_args */, server_addresses->addrs, - grpc_core::ExecCtx::Get()->Now() + 1000); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_tcp_client_connect(state.closure(), &endpoint_, pollset_set, args, + server_addresses->addrs, + grpc_core::ExecCtx::Get()->Now() + 1000); + grpc_channel_args_destroy(args); ASSERT_TRUE(PollUntilDone( &state, grpc_timespec_to_millis_round_up(gpr_inf_future(GPR_CLOCK_MONOTONIC)))); diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 3a3a73b3028..e1fb6ffb9dd 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -46,7 +46,6 @@ grpc_cc_library( "port_server_client.cc", "reconnect_server.cc", "resolve_localhost_ip46.cc", - "resource_user_util.cc", "slice_splitter.cc", "subprocess_posix.cc", "subprocess_windows.cc", @@ -69,7 +68,6 @@ grpc_cc_library( "port_server_client.h", "reconnect_server.h", "resolve_localhost_ip46.h", - "resource_user_util.h", "slice_splitter.h", "subprocess.h", "test_config.h", diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index f3fa7a3e8d0..4997a535d0b 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -36,7 +36,6 @@ typedef struct mock_endpoint { grpc_slice_buffer read_buffer; grpc_slice_buffer* on_read_out; grpc_closure* on_read; - grpc_slice_allocator* slice_allocator; } mock_endpoint; static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, @@ -87,7 +86,6 @@ static void me_shutdown(grpc_endpoint* ep, grpc_error_handle why) { static void me_destroy(grpc_endpoint* ep) { mock_endpoint* m = reinterpret_cast(ep); grpc_slice_buffer_destroy(&m->read_buffer); - grpc_slice_allocator_destroy(m->slice_allocator); gpr_mu_destroy(&m->mu); gpr_free(m); } @@ -116,11 +114,9 @@ static const grpc_endpoint_vtable vtable = {me_read, me_get_fd, me_can_track_err}; -grpc_endpoint* grpc_mock_endpoint_create( - void (*on_write)(grpc_slice slice), grpc_slice_allocator* slice_allocator) { +grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice)) { mock_endpoint* m = static_cast(gpr_malloc(sizeof(*m))); m->base.vtable = &vtable; - m->slice_allocator = slice_allocator; grpc_slice_buffer_init(&m->read_buffer); gpr_mu_init(&m->mu); m->on_write = on_write; diff --git a/test/core/util/mock_endpoint.h b/test/core/util/mock_endpoint.h index dbb6c0f528b..6d52390e094 100644 --- a/test/core/util/mock_endpoint.h +++ b/test/core/util/mock_endpoint.h @@ -21,8 +21,7 @@ #include "src/core/lib/iomgr/endpoint.h" -grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice), - grpc_slice_allocator* slice_allocator); +grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice)); void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice); #endif diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 50534f7ae9d..da509bcbd27 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -30,7 +30,6 @@ #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/slice/slice_internal.h" -#include "test/core/util/resource_user_util.h" typedef struct passthru_endpoint passthru_endpoint; @@ -40,7 +39,6 @@ typedef struct { grpc_slice_buffer read_buffer; grpc_slice_buffer* on_read_out; grpc_closure* on_read; - grpc_slice_allocator* slice_allocator; } half; struct passthru_endpoint { @@ -138,8 +136,6 @@ static void me_destroy(grpc_endpoint* ep) { grpc_passthru_endpoint_stats_destroy(p->stats); grpc_slice_buffer_destroy_internal(&p->client.read_buffer); grpc_slice_buffer_destroy_internal(&p->server.read_buffer); - grpc_slice_allocator_destroy(p->client.slice_allocator); - grpc_slice_allocator_destroy(p->server.slice_allocator); gpr_free(p); } else { gpr_mu_unlock(&p->mu); @@ -179,7 +175,6 @@ static const grpc_endpoint_vtable vtable = { }; static void half_init(half* m, passthru_endpoint* parent, - grpc_slice_allocator* slice_allocator, const char* half_name) { m->base.vtable = &vtable; m->parent = parent; @@ -187,7 +182,6 @@ static void half_init(half* m, passthru_endpoint* parent, m->on_read = nullptr; std::string name = absl::StrFormat("passthru_endpoint_%s_%p", half_name, parent); - m->slice_allocator = slice_allocator; } void grpc_passthru_endpoint_create(grpc_endpoint** client, @@ -203,8 +197,8 @@ void grpc_passthru_endpoint_create(grpc_endpoint** client, gpr_ref(&stats->refs); m->stats = stats; } - half_init(&m->client, m, grpc_slice_allocator_create_unlimited(), "client"); - half_init(&m->server, m, grpc_slice_allocator_create_unlimited(), "server"); + half_init(&m->client, m, "client"); + half_init(&m->server, m, "server"); gpr_mu_init(&m->mu); *client = &m->client.base; *server = &m->server.base; diff --git a/test/core/util/port_server_client.cc b/test/core/util/port_server_client.cc index 70a253f17c2..36124362c63 100644 --- a/test/core/util/port_server_client.cc +++ b/test/core/util/port_server_client.cc @@ -85,9 +85,8 @@ void grpc_free_port_using_server(int port) { req.http.path = path; grpc_httpcli_context_init(&context); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("port_server_client/free"); - grpc_httpcli_get(&context, &pr.pops, resource_quota, &req, + grpc_httpcli_get(&context, &pr.pops, grpc_core::ResourceQuota::Default(), + &req, grpc_core::ExecCtx::Get()->Now() + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(freed_port_from_server, &pr, grpc_schedule_on_exec_ctx), @@ -167,9 +166,8 @@ static void got_port_from_server(void* arg, grpc_error_handle error) { req.http.path = const_cast("/get"); grpc_http_response_destroy(&pr->response); pr->response = {}; - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("port_server_client/pick_retry"); - grpc_httpcli_get(pr->ctx, &pr->pops, resource_quota, &req, + grpc_httpcli_get(pr->ctx, &pr->pops, grpc_core::ResourceQuota::Default(), + &req, grpc_core::ExecCtx::Get()->Now() + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(got_port_from_server, pr, grpc_schedule_on_exec_ctx), @@ -216,9 +214,8 @@ int grpc_pick_port_using_server(void) { req.http.path = const_cast("/get"); grpc_httpcli_context_init(&context); - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("port_server_client/pick"); - grpc_httpcli_get(&context, &pr.pops, resource_quota, &req, + grpc_httpcli_get(&context, &pr.pops, grpc_core::ResourceQuota::Default(), + &req, grpc_core::ExecCtx::Get()->Now() + 30 * GPR_MS_PER_SEC, GRPC_CLOSURE_CREATE(got_port_from_server, &pr, grpc_schedule_on_exec_ctx), diff --git a/test/core/util/resource_user_util.cc b/test/core/util/resource_user_util.cc deleted file mode 100644 index 2fa609c944b..00000000000 --- a/test/core/util/resource_user_util.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2021 The gRPC Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "test/core/util/resource_user_util.h" - -#include "absl/strings/str_format.h" - -grpc_resource_user* grpc_resource_user_create_unlimited( - grpc_resource_quota* resource_quota) { - if (resource_quota == nullptr) { - resource_quota = grpc_resource_quota_create("anonymous mock quota"); - } else { - grpc_resource_quota_ref_internal(resource_quota); - } - grpc_resource_user* ru = nullptr; - ru = grpc_resource_user_create( - resource_quota, absl::StrFormat("mock_resource_user_%" PRIxPTR, - reinterpret_cast(&ru)) - .c_str()); - grpc_resource_quota_unref_internal(resource_quota); - return ru; -} - -grpc_slice_allocator* grpc_slice_allocator_create_unlimited() { - grpc_resource_quota* resource_quota = - grpc_resource_quota_create("anonymous mock quota"); - grpc_slice_allocator* slice_allocator = grpc_slice_allocator_create( - resource_quota, - absl::StrFormat("mock_resource_user_from_quota:%p", resource_quota)); - grpc_resource_quota_unref(resource_quota); - return slice_allocator; -} diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 048d2f9d946..4cb63516044 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -31,6 +31,7 @@ #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/iomgr/socket_utils.h" #include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/resource_quota/api.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -65,10 +66,11 @@ void test_tcp_server_start(test_tcp_server* server, int port) { memset(&addr->sin_addr, 0, sizeof(addr->sin_addr)); resolved_addr.len = static_cast(sizeof(grpc_sockaddr_in)); - grpc_error_handle error = grpc_tcp_server_create( - &server->shutdown_complete, nullptr, - grpc_slice_allocator_factory_create(grpc_resource_quota_create(nullptr)), - &server->tcp_server); + grpc_channel_args* args = + grpc_core::EnsureResourceQuotaInChannelArgs(nullptr); + grpc_error_handle error = grpc_tcp_server_create(&server->shutdown_complete, + args, &server->tcp_server); + grpc_channel_args_destroy(args); GPR_ASSERT(error == GRPC_ERROR_NONE); error = grpc_tcp_server_add_port(server->tcp_server, &resolved_addr, &port_added); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 3892400fba0..d8f9f75bebd 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -83,7 +83,6 @@ namespace { gpr_atm g_connection_delay_ms; void tcp_client_connect_with_delay(grpc_closure* closure, grpc_endpoint** ep, - grpc_slice_allocator* slice_allocator, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, const grpc_resolved_address* addr, @@ -92,8 +91,8 @@ void tcp_client_connect_with_delay(grpc_closure* closure, grpc_endpoint** ep, if (delay_ms > 0) { gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms)); } - default_client_impl->connect(closure, ep, slice_allocator, interested_parties, - channel_args, addr, deadline + delay_ms); + default_client_impl->connect(closure, ep, interested_parties, channel_args, + addr, deadline + delay_ms); } grpc_tcp_client_vtable delayed_connect = {tcp_client_connect_with_delay}; diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 4c756c131b1..02e8952a61f 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -45,7 +45,6 @@ #include "src/core/lib/transport/transport_impl.h" #include "src/cpp/client/create_channel_internal.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" @@ -705,9 +704,8 @@ class IsolatedCallFixture : public TrackCounters { nullptr)); { grpc_core::ExecCtx exec_ctx; - channel_ = grpc_channel_create_with_builder( - builder, GRPC_CLIENT_CHANNEL, grpc_resource_user_create_unlimited(), - 0); + channel_ = grpc_channel_create_with_builder(builder, GRPC_CLIENT_CHANNEL, + nullptr); } cq_ = grpc_completion_queue_create_for_next(nullptr); } diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 7aaa338f58c..542dd68bb7c 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -34,10 +34,9 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/iomgr/resource_quota.h" +#include "src/core/lib/resource_quota/api.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/static_metadata.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" @@ -134,8 +133,10 @@ class Fixture { Fixture(const grpc::ChannelArguments& args, bool client) { grpc_channel_args c_args = args.c_channel_args(); ep_ = new PhonyEndpoint; - t_ = grpc_create_chttp2_transport(&c_args, ep_, client, - grpc_resource_user_create_unlimited()); + grpc_channel_args* final_args = + grpc_core::EnsureResourceQuotaInChannelArgs(&c_args); + t_ = grpc_create_chttp2_transport(final_args, ep_, client); + grpc_channel_args_destroy(final_args); grpc_chttp2_transport_start_reading(t_, nullptr, nullptr, nullptr); FlushExecCtx(); } diff --git a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h index f2e6657bb58..3772a4943ca 100644 --- a/test/cpp/microbenchmarks/callback_streaming_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_streaming_ping_pong.h @@ -25,7 +25,6 @@ #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/resource_user_util.h" #include "test/cpp/microbenchmarks/callback_test_service.h" #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" diff --git a/test/cpp/microbenchmarks/callback_unary_ping_pong.h b/test/cpp/microbenchmarks/callback_unary_ping_pong.h index b058611f0be..039226bb438 100644 --- a/test/cpp/microbenchmarks/callback_unary_ping_pong.h +++ b/test/cpp/microbenchmarks/callback_unary_ping_pong.h @@ -27,7 +27,6 @@ #include "src/core/lib/profiling/timers.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/resource_user_util.h" #include "test/cpp/microbenchmarks/callback_test_service.h" #include "test/cpp/microbenchmarks/fullstack_context_mutators.h" #include "test/cpp/microbenchmarks/fullstack_fixtures.h" diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 86e15347fe8..8901dd83978 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -51,6 +51,7 @@ class FixtureConfiguration { virtual void ApplyCommonChannelArguments(ChannelArguments* c) const { c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); + c->SetResourceQuota(ResourceQuota()); } virtual void ApplyCommonServerBuilderConfig(ServerBuilder* b) const { @@ -174,12 +175,8 @@ class EndpointPairFixture : public BaseFixture { { const grpc_channel_args* server_args = server_->c_server()->core_server->channel_args(); - grpc_resource_quota* server_resource_quota = - grpc_resource_quota_from_channel_args(server_args, true); server_transport_ = grpc_create_chttp2_transport( - server_args, endpoints.server, false /* is_client */, - grpc_resource_user_create(server_resource_quota, "server_transport")); - grpc_resource_quota_unref(server_resource_quota); + server_args, endpoints.server, false /* is_client */); for (grpc_pollset* pollset : server_->c_server()->core_server->pollsets()) { grpc_endpoint_add_to_pollset(endpoints.server, pollset); @@ -200,16 +197,12 @@ class EndpointPairFixture : public BaseFixture { fixture_configuration.ApplyCommonChannelArguments(&args); grpc_channel_args c_args = args.c_channel_args(); - grpc_resource_quota* client_resource_quota = - grpc_resource_quota_from_channel_args(&c_args, true); - client_transport_ = grpc_create_chttp2_transport( - &c_args, endpoints.client, true, - grpc_resource_user_create(client_resource_quota, "client_transport")); - grpc_resource_quota_unref(client_resource_quota); + client_transport_ = + grpc_create_chttp2_transport(&c_args, endpoints.client, true); GPR_ASSERT(client_transport_); grpc_channel* channel = grpc_channel_create("target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, - client_transport_, nullptr, 0, nullptr); + client_transport_, nullptr); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr, nullptr); diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 900d55df5d1..365a0eb606c 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -40,7 +40,6 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/passthru_endpoint.h" #include "test/core/util/port.h" -#include "test/core/util/resource_user_util.h" #include "test/core/util/test_config.h" namespace grpc { @@ -56,6 +55,7 @@ static void ApplyCommonServerBuilderConfig(ServerBuilder* b) { static void ApplyCommonChannelArguments(ChannelArguments* c) { c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); + c->SetResourceQuota(ResourceQuota()); } class EndpointPairFixture { @@ -74,8 +74,7 @@ class EndpointPairFixture { const grpc_channel_args* server_args = server_->c_server()->core_server->channel_args(); grpc_transport* transport = grpc_create_chttp2_transport( - server_args, endpoints.server, false /* is_client */, - grpc_resource_user_create_unlimited()); + server_args, endpoints.server, false /* is_client */); for (grpc_pollset* pollset : server_->c_server()->core_server->pollsets()) { grpc_endpoint_add_to_pollset(endpoints.server, pollset); @@ -95,12 +94,10 @@ class EndpointPairFixture { grpc_channel_args c_args = args.c_channel_args(); grpc_transport* transport = - grpc_create_chttp2_transport(&c_args, endpoints.client, true, - grpc_resource_user_create_unlimited()); + grpc_create_chttp2_transport(&c_args, endpoints.client, true); GPR_ASSERT(transport); - grpc_channel* channel = - grpc_channel_create("target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, - transport, nullptr, 0, nullptr); + grpc_channel* channel = grpc_channel_create( + "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport, nullptr); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr, nullptr); channel_ = ::grpc::CreateChannelInternal( diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index f786ae43075..c13b25f8c62 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -885,6 +885,7 @@ include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ +include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 4e7b50256a2..a732113f407 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -885,6 +885,7 @@ include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ +include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ @@ -1766,6 +1767,7 @@ src/core/lib/event_engine/channel_args_endpoint_config.h \ src/core/lib/event_engine/event_engine.cc \ src/core/lib/event_engine/event_engine_factory.cc \ src/core/lib/event_engine/event_engine_factory.h \ +src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/sockaddr.cc \ src/core/lib/event_engine/sockaddr.h \ src/core/lib/gpr/alloc.cc \ @@ -1815,6 +1817,7 @@ src/core/lib/gprpp/atomic_utils.h \ src/core/lib/gprpp/bitset.h \ src/core/lib/gprpp/chunked_vector.h \ src/core/lib/gprpp/construct_destruct.h \ +src/core/lib/gprpp/cpp_impl_of.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/dual_ref_counted.h \ src/core/lib/gprpp/examine_stack.cc \ @@ -1964,8 +1967,6 @@ src/core/lib/iomgr/resolve_address_custom.cc \ src/core/lib/iomgr/resolve_address_custom.h \ src/core/lib/iomgr/resolve_address_posix.cc \ src/core/lib/iomgr/resolve_address_windows.cc \ -src/core/lib/iomgr/resource_quota.cc \ -src/core/lib/iomgr/resource_quota.h \ src/core/lib/iomgr/sockaddr.h \ src/core/lib/iomgr/sockaddr_posix.h \ src/core/lib/iomgr/sockaddr_windows.h \ @@ -2037,6 +2038,30 @@ src/core/lib/matchers/matchers.h \ src/core/lib/profiling/basic_timers.cc \ src/core/lib/profiling/stap_timers.cc \ src/core/lib/profiling/timers.h \ +src/core/lib/promise/activity.cc \ +src/core/lib/promise/activity.h \ +src/core/lib/promise/context.h \ +src/core/lib/promise/detail/basic_seq.h \ +src/core/lib/promise/detail/promise_factory.h \ +src/core/lib/promise/detail/promise_like.h \ +src/core/lib/promise/detail/status.h \ +src/core/lib/promise/detail/switch.h \ +src/core/lib/promise/exec_ctx_wakeup_scheduler.h \ +src/core/lib/promise/loop.h \ +src/core/lib/promise/map.h \ +src/core/lib/promise/poll.h \ +src/core/lib/promise/race.h \ +src/core/lib/promise/seq.h \ +src/core/lib/resource_quota/api.cc \ +src/core/lib/resource_quota/api.h \ +src/core/lib/resource_quota/memory_quota.cc \ +src/core/lib/resource_quota/memory_quota.h \ +src/core/lib/resource_quota/resource_quota.cc \ +src/core/lib/resource_quota/resource_quota.h \ +src/core/lib/resource_quota/thread_quota.cc \ +src/core/lib/resource_quota/thread_quota.h \ +src/core/lib/resource_quota/trace.cc \ +src/core/lib/resource_quota/trace.h \ src/core/lib/security/authorization/authorization_engine.h \ src/core/lib/security/authorization/authorization_policy_provider.h \ src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 33635c4653a..7ad67d1da24 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -815,6 +815,7 @@ include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ +include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1f32d854d7c..c704210eaae 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -815,6 +815,7 @@ include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/memory_allocator.h \ +include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/port.h \ include/grpc/fork.h \ include/grpc/grpc.h \ @@ -1562,6 +1563,7 @@ src/core/lib/event_engine/channel_args_endpoint_config.h \ src/core/lib/event_engine/event_engine.cc \ src/core/lib/event_engine/event_engine_factory.cc \ src/core/lib/event_engine/event_engine_factory.h \ +src/core/lib/event_engine/memory_allocator.cc \ src/core/lib/event_engine/sockaddr.cc \ src/core/lib/event_engine/sockaddr.h \ src/core/lib/gpr/README.md \ @@ -1613,6 +1615,7 @@ src/core/lib/gprpp/atomic_utils.h \ src/core/lib/gprpp/bitset.h \ src/core/lib/gprpp/chunked_vector.h \ src/core/lib/gprpp/construct_destruct.h \ +src/core/lib/gprpp/cpp_impl_of.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/dual_ref_counted.h \ src/core/lib/gprpp/examine_stack.cc \ @@ -1763,8 +1766,6 @@ src/core/lib/iomgr/resolve_address_custom.cc \ src/core/lib/iomgr/resolve_address_custom.h \ src/core/lib/iomgr/resolve_address_posix.cc \ src/core/lib/iomgr/resolve_address_windows.cc \ -src/core/lib/iomgr/resource_quota.cc \ -src/core/lib/iomgr/resource_quota.h \ src/core/lib/iomgr/sockaddr.h \ src/core/lib/iomgr/sockaddr_posix.h \ src/core/lib/iomgr/sockaddr_windows.h \ @@ -1836,6 +1837,30 @@ src/core/lib/matchers/matchers.h \ src/core/lib/profiling/basic_timers.cc \ src/core/lib/profiling/stap_timers.cc \ src/core/lib/profiling/timers.h \ +src/core/lib/promise/activity.cc \ +src/core/lib/promise/activity.h \ +src/core/lib/promise/context.h \ +src/core/lib/promise/detail/basic_seq.h \ +src/core/lib/promise/detail/promise_factory.h \ +src/core/lib/promise/detail/promise_like.h \ +src/core/lib/promise/detail/status.h \ +src/core/lib/promise/detail/switch.h \ +src/core/lib/promise/exec_ctx_wakeup_scheduler.h \ +src/core/lib/promise/loop.h \ +src/core/lib/promise/map.h \ +src/core/lib/promise/poll.h \ +src/core/lib/promise/race.h \ +src/core/lib/promise/seq.h \ +src/core/lib/resource_quota/api.cc \ +src/core/lib/resource_quota/api.h \ +src/core/lib/resource_quota/memory_quota.cc \ +src/core/lib/resource_quota/memory_quota.h \ +src/core/lib/resource_quota/resource_quota.cc \ +src/core/lib/resource_quota/resource_quota.h \ +src/core/lib/resource_quota/thread_quota.cc \ +src/core/lib/resource_quota/thread_quota.h \ +src/core/lib/resource_quota/trace.cc \ +src/core/lib/resource_quota/trace.h \ src/core/lib/security/authorization/authorization_engine.h \ src/core/lib/security/authorization/authorization_policy_provider.h \ src/core/lib/security/authorization/authorization_policy_provider_vtable.cc \ diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 869807910a7..4ac6a3f5e3b 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2671,30 +2671,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "test_core_iomgr_resource_quota_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -4099,6 +4075,30 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "cpp_impl_of_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -6105,6 +6105,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "resource_quota_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, @@ -6861,30 +6885,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "test_core_resource_quota_resource_quota_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": false - }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 1d751d8f715..fe2ab782854 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -25,9 +25,9 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..')) # map of banned function signature to allowlist BANNED_EXCEPT = { 'grpc_slice_from_static_buffer(': ['src/core/lib/slice/slice.cc'], - 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.cc'], + 'grpc_resource_quota_ref(': ['src/core/lib/resource_quota/api.cc'], 'grpc_resource_quota_unref(': [ - 'src/core/lib/iomgr/resource_quota.cc', 'src/core/lib/surface/server.cc' + 'src/core/lib/resource_quota/api.cc', 'src/core/lib/surface/server.cc' ], 'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.cc'], 'grpc_slice_buffer_reset_and_unref(': [