diff options
-rw-r--r-- | CMakeLists.txt | 42 | ||||
-rw-r--r-- | Makefile | 48 | ||||
-rw-r--r-- | build.yaml | 12 | ||||
-rw-r--r-- | src/core/lib/debug/stats_data.c | 75 | ||||
-rw-r--r-- | src/core/lib/debug/stats_data.h | 88 | ||||
-rw-r--r-- | test/core/debug/stats_test.cc | 127 | ||||
-rwxr-xr-x | tools/codegen/core/gen_stats_data.py | 47 | ||||
-rw-r--r-- | tools/run_tests/generated/sources_and_headers.json | 18 | ||||
-rw-r--r-- | tools/run_tests/generated/tests.json | 22 |
9 files changed, 386 insertions, 93 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index efc33c0a6c..0567255dd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -756,6 +756,7 @@ endif() add_dependencies(buildtests_cxx server_crash_test_client) add_dependencies(buildtests_cxx server_request_call_test) add_dependencies(buildtests_cxx shutdown_test) +add_dependencies(buildtests_cxx stats_test) add_dependencies(buildtests_cxx status_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx streaming_throughput_test) @@ -12688,6 +12689,47 @@ target_link_libraries(shutdown_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(stats_test + test/core/debug/stats_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(stats_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CARES_BUILD_INCLUDE_DIR} + PRIVATE ${CARES_INCLUDE_DIR} + PRIVATE ${CARES_PLATFORM_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(stats_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(status_test test/cpp/util/status_test.cc third_party/googletest/googletest/src/gtest-all.cc @@ -1170,6 +1170,7 @@ server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test +stats_test: $(BINDIR)/$(CONFIG)/stats_test status_test: $(BINDIR)/$(CONFIG)/status_test streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test stress_test: $(BINDIR)/$(CONFIG)/stress_test @@ -1600,6 +1601,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/server_request_call_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ + $(BINDIR)/$(CONFIG)/stats_test \ $(BINDIR)/$(CONFIG)/status_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ @@ -1715,6 +1717,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/server_request_call_test \ $(BINDIR)/$(CONFIG)/shutdown_test \ + $(BINDIR)/$(CONFIG)/stats_test \ $(BINDIR)/$(CONFIG)/status_test \ $(BINDIR)/$(CONFIG)/streaming_throughput_test \ $(BINDIR)/$(CONFIG)/stress_test \ @@ -2114,6 +2117,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" $(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 ) + $(E) "[RUN] Testing stats_test" + $(Q) $(BINDIR)/$(CONFIG)/stats_test || ( echo test stats_test failed ; exit 1 ) $(E) "[RUN] Testing status_test" $(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 ) $(E) "[RUN] Testing streaming_throughput_test" @@ -16631,6 +16636,49 @@ endif endif +STATS_TEST_SRC = \ + test/core/debug/stats_test.cc \ + +STATS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STATS_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/stats_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/stats_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/stats_test: $(PROTOBUF_DEP) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/stats_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/debug/stats_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_stats_test: $(STATS_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(STATS_TEST_OBJS:.o=.dep) +endif +endif + + STATUS_TEST_SRC = \ test/cpp/util/status_test.cc \ diff --git a/build.yaml b/build.yaml index a43ad6ae31..2b69888e06 100644 --- a/build.yaml +++ b/build.yaml @@ -4515,6 +4515,18 @@ targets: - grpc - gpr_test_util - gpr +- name: stats_test + gtest: true + build: test + language: c++ + src: + - test/core/debug/stats_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: status_test build: test language: c++ diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c index 177234ab5b..0ba10e68e3 100644 --- a/src/core/lib/debug/stats_data.c +++ b/src/core/lib/debug/stats_data.c @@ -19,6 +19,8 @@ */ #include "src/core/lib/debug/stats_data.h" +#include "src/core/lib/debug/stats.h" +#include "src/core/lib/iomgr/exec_ctx.h" const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = { "client_calls_created", "server_calls_created", "syscall_write", "syscall_read", "syscall_poll", "syscall_wait", @@ -165,7 +167,80 @@ const uint8_t grpc_stats_table_3[52] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52}; +void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, double value) { + union { + double dbl; + uint64_t uint; + } _val; + _val.dbl = value; + if (_val.dbl < 0) _val.dbl = 0; + if (_val.dbl < 5.000000) { + GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, + (int)_val.dbl); + } else { + if (_val.uint < 4715268809856909312ull) { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, + grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4); + } else { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, + grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, + grpc_stats_table_0, 64)); + } + } +} +void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double value) { + union { + double dbl; + uint64_t uint; + } _val; + _val.dbl = value; + if (_val.dbl < 0) _val.dbl = 0; + if (_val.dbl < 12.000000) { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, (int)_val.dbl); + } else { + if (_val.uint < 4652218415073722368ull) { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, + grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 49)] + + 11); + } else { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, + grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, + grpc_stats_table_2, 64)); + } + } +} +void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, double value) { + union { + double dbl; + uint64_t uint; + } _val; + _val.dbl = value; + if (_val.dbl < 0) _val.dbl = 0; + if (_val.dbl < 5.000000) { + GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, + (int)_val.dbl); + } else { + if (_val.uint < 4715268809856909312ull) { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, + grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4); + } else { + GRPC_STATS_INC_HISTOGRAM( + (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, + grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, + grpc_stats_table_0, 64)); + } + } +} const int grpc_stats_histo_buckets[3] = {64, 64, 64}; const int grpc_stats_histo_start[3] = {0, 64, 128}; const double *const grpc_stats_histo_bucket_boundaries[3] = { grpc_stats_table_0, grpc_stats_table_2, grpc_stats_table_0}; +void (*const grpc_stats_inc_histogram[3])(grpc_exec_ctx *exec_ctx, double x) = { + grpc_stats_inc_tcp_write_size, grpc_stats_inc_tcp_write_iov_size, + grpc_stats_inc_tcp_read_size}; diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h index 9a4ba68655..4fff769450 100644 --- a/src/core/lib/debug/stats_data.h +++ b/src/core/lib/debug/stats_data.h @@ -22,6 +22,7 @@ #define GRPC_CORE_LIB_DEBUG_STATS_DATA_H #include <inttypes.h> +#include "src/core/lib/iomgr/exec_ctx.h" typedef enum { GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED, @@ -64,84 +65,19 @@ typedef enum { GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_WAIT) #define GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS(exec_ctx) \ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HISTOGRAM_SLOW_LOOKUPS) -#define GRPC_STATS_INC_TCP_WRITE_SIZE(exec_ctx, value) \ - do { \ - union { \ - double dbl; \ - uint64_t uint; \ - } _val; \ - _val.dbl = (double)(value); \ - if (_val.dbl < 0) _val.dbl = 0; \ - if (_val.dbl < 5.000000) { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, (int)_val.dbl); \ - } else { \ - if (_val.uint < 4715268809856909312ull) { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, \ - grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \ - } else { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE, \ - grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \ - grpc_stats_table_0, 64)); \ - } \ - } \ - } while (false) -#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(exec_ctx, value) \ - do { \ - union { \ - double dbl; \ - uint64_t uint; \ - } _val; \ - _val.dbl = (double)(value); \ - if (_val.dbl < 0) _val.dbl = 0; \ - if (_val.dbl < 12.000000) { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, (int)_val.dbl); \ - } else { \ - if (_val.uint < 4652218415073722368ull) { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, \ - grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 49)]); \ - } else { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, \ - grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \ - grpc_stats_table_2, 64)); \ - } \ - } \ - } while (false) -#define GRPC_STATS_INC_TCP_READ_SIZE(exec_ctx, value) \ - do { \ - union { \ - double dbl; \ - uint64_t uint; \ - } _val; \ - _val.dbl = (double)(value); \ - if (_val.dbl < 0) _val.dbl = 0; \ - if (_val.dbl < 5.000000) { \ - GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \ - (int)_val.dbl); \ - } else { \ - if (_val.uint < 4715268809856909312ull) { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \ - grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \ - } else { \ - GRPC_STATS_INC_HISTOGRAM( \ - (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_SIZE, \ - grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \ - grpc_stats_table_0, 64)); \ - } \ - } \ - } while (false) -extern const double grpc_stats_table_0[64]; -extern const uint8_t grpc_stats_table_1[87]; -extern const double grpc_stats_table_2[64]; -extern const uint8_t grpc_stats_table_3[52]; +#define GRPC_STATS_INC_TCP_WRITE_SIZE(exec_ctx, value) \ + grpc_stats_inc_tcp_write_size((exec_ctx), (double)(value)) +void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, double x); +#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(exec_ctx, value) \ + grpc_stats_inc_tcp_write_iov_size((exec_ctx), (double)(value)) +void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double x); +#define GRPC_STATS_INC_TCP_READ_SIZE(exec_ctx, value) \ + grpc_stats_inc_tcp_read_size((exec_ctx), (double)(value)) +void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, double x); extern const int grpc_stats_histo_buckets[3]; extern const int grpc_stats_histo_start[3]; extern const double *const grpc_stats_histo_bucket_boundaries[3]; +extern void (*const grpc_stats_inc_histogram[3])(grpc_exec_ctx *exec_ctx, + double x); #endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */ diff --git a/test/core/debug/stats_test.cc b/test/core/debug/stats_test.cc new file mode 100644 index 0000000000..65ccc7a5c8 --- /dev/null +++ b/test/core/debug/stats_test.cc @@ -0,0 +1,127 @@ +/* + * + * Copyright 2017 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. + * + */ + +extern "C" { +#include "src/core/lib/debug/stats.h" +} + +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <gtest/gtest.h> + +namespace grpc { +namespace testing { + +class Snapshot { + public: + Snapshot() { grpc_stats_collect(&begin_); } + + grpc_stats_data delta() { + grpc_stats_data now; + grpc_stats_collect(&now); + grpc_stats_data delta; + grpc_stats_diff(&now, &begin_, &delta); + return delta; + } + + private: + grpc_stats_data begin_; +}; + +TEST(StatsTest, IncCounters) { + for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) { + Snapshot snapshot; + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_STATS_INC_COUNTER(&exec_ctx, (grpc_stats_counters)i); + grpc_exec_ctx_finish(&exec_ctx); + + EXPECT_EQ(snapshot.delta().counters[i], 1); + } +} + +TEST(StatsTest, IncSpecificCounter) { + Snapshot snapshot; + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_STATS_INC_SYSCALL_POLL(&exec_ctx); + grpc_exec_ctx_finish(&exec_ctx); + + EXPECT_EQ(snapshot.delta().counters[GRPC_STATS_COUNTER_SYSCALL_POLL], 1); +} + +static int FindExpectedBucket(int i, int j) { + if (j < 0) { + return 0; + } + if (j >= + grpc_stats_histo_bucket_boundaries[i][grpc_stats_histo_buckets[i] - 1]) { + return grpc_stats_histo_buckets[i] - 1; + } + int r = 0; + while (grpc_stats_histo_bucket_boundaries[i][r + 1] <= j) r++; + return r; +} + +static int FindNonZeroBucket(const grpc_stats_data& data, int i) { + for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) { + if (data.histograms[grpc_stats_histo_start[i] + j] != 0) { + return j; + } + } + return -1; +} + +TEST(StatsTest, IncHistogram) { + for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) { + for (int j = -1000; + j < + grpc_stats_histo_bucket_boundaries[i] + [grpc_stats_histo_buckets[i] - 1] + + 1000; + j++) { + gpr_log(GPR_DEBUG, "histo:%d value:%d", i, j); + + Snapshot snapshot; + + int expected_bucket = FindExpectedBucket(i, j); + + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_stats_inc_histogram[i](&exec_ctx, j); + grpc_exec_ctx_finish(&exec_ctx); + + auto delta = snapshot.delta(); + int got_bucket = FindNonZeroBucket(delta, i); + + EXPECT_EQ(expected_bucket, got_bucket); + EXPECT_EQ(delta.histograms[grpc_stats_histo_start[i] + expected_bucket], + 1); + } + } +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_init(); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py index 85489eb7dc..8ae8f6b831 100755 --- a/tools/codegen/core/gen_stats_data.py +++ b/tools/codegen/core/gen_stats_data.py @@ -125,32 +125,30 @@ def gen_bucket_code(histogram): shift_data = find_ideal_shift(code_bounds[first_nontrivial:], 256 * histogram.buckets) print first_nontrivial, shift_data, bounds if shift_data is not None: print [hex(x >> shift_data[0]) for x in code_bounds[first_nontrivial:]] - code = 'do {\\\n' - code += ' union { double dbl; uint64_t uint; } _val;\\\n' - code += '_val.dbl = (double)(value);\\\n' - code += 'if (_val.dbl < 0) _val.dbl = 0;\\\n' + code = ' union { double dbl; uint64_t uint; } _val;\n' + code += '_val.dbl = value;\n' + code += 'if (_val.dbl < 0) _val.dbl = 0;\n' map_table = gen_map_table(code_bounds[first_nontrivial:], shift_data) if first_nontrivial is None: - code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\\\n' + code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\n' % histogram.name.upper()) else: - code += 'if (_val.dbl < %f) {\\\n' % first_nontrivial - code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\\\n' + code += 'if (_val.dbl < %f) {\n' % first_nontrivial + code += ('GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, (int)_val.dbl);\n' % histogram.name.upper()) code += '} else {' first_nontrivial_code = dbl2u64(first_nontrivial) if shift_data is not None: map_table_idx = decl_static_table(map_table, type_for_uint_table(map_table)) - code += 'if (_val.uint < %dull) {\\\n' % ((map_table[-1] << shift_data[0]) + first_nontrivial_code) + code += 'if (_val.uint < %dull) {\n' % ((map_table[-1] << shift_data[0]) + first_nontrivial_code) code += 'GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, ' % histogram.name.upper() - code += 'grpc_stats_table_%d[((_val.uint - %dull) >> %d)]);\\\n' % (map_table_idx, first_nontrivial_code, shift_data[0]) - code += '} else {\\\n' + code += 'grpc_stats_table_%d[((_val.uint - %dull) >> %d)] + %d);\n' % (map_table_idx, first_nontrivial_code, shift_data[0], first_nontrivial-1) + code += '} else {\n' code += 'GRPC_STATS_INC_HISTOGRAM((exec_ctx), GRPC_STATS_HISTOGRAM_%s, '% histogram.name.upper() - code += 'grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, grpc_stats_table_%d, %d));\\\n' % (bounds_idx, len(bounds)) + code += 'grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, grpc_stats_table_%d, %d));\n' % (bounds_idx, len(bounds)) if shift_data is not None: code += '}' code += '}' - code += '} while (false)' return (code, bounds_idx) # utility: print a big comment block into a set of files @@ -184,6 +182,7 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H: print >>H, "#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H" print >>H print >>H, "#include <inttypes.h>" + print >>H, "#include \"src/core/lib/iomgr/exec_ctx.h\"" print >>H for typename, instances in sorted(inst_map.items()): @@ -215,11 +214,9 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H: "GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_%s)") % ( ctr.name.upper(), ctr.name.upper()) for histogram in inst_map['Histogram']: - code, bounds_idx = gen_bucket_code(histogram) - histo_bucket_boundaries.append(bounds_idx) - print >>H, ("#define GRPC_STATS_INC_%s(exec_ctx, value) %s") % ( - histogram.name.upper(), - code) + print >>H, "#define GRPC_STATS_INC_%s(exec_ctx, value) grpc_stats_inc_%s((exec_ctx), (double)(value))" % ( + histogram.name.upper(), histogram.name.lower()) + print >>H, "void grpc_stats_inc_%s(grpc_exec_ctx *exec_ctx, double x);" % histogram.name.lower() for i, tbl in enumerate(static_tables): print >>H, "extern const %s grpc_stats_table_%d[%d];" % (tbl[0], i, len(tbl[1])) @@ -227,6 +224,7 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H: print >>H, "extern const int grpc_stats_histo_buckets[%d];" % len(inst_map['Histogram']) print >>H, "extern const int grpc_stats_histo_start[%d];" % len(inst_map['Histogram']) print >>H, "extern const double *const grpc_stats_histo_bucket_boundaries[%d];" % len(inst_map['Histogram']) + print >>H, "extern void (*const grpc_stats_inc_histogram[%d])(grpc_exec_ctx *exec_ctx, double x);" % len(inst_map['Histogram']) print >>H print >>H, "#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */" @@ -250,6 +248,14 @@ with open('src/core/lib/debug/stats_data.c', 'w') as C: put_banner([C], ["Automatically generated by tools/codegen/core/gen_stats_data.py"]) print >>C, "#include \"src/core/lib/debug/stats_data.h\"" + print >>C, "#include \"src/core/lib/debug/stats.h\"" + print >>C, "#include \"src/core/lib/iomgr/exec_ctx.h\"" + + histo_code = [] + for histogram in inst_map['Histogram']: + code, bounds_idx = gen_bucket_code(histogram) + histo_bucket_boundaries.append(bounds_idx) + histo_code.append(code) for typename, instances in sorted(inst_map.items()): print >>C, "const char *grpc_stats_%s_name[GRPC_STATS_%s_COUNT] = {" % ( @@ -261,9 +267,16 @@ with open('src/core/lib/debug/stats_data.c', 'w') as C: print >>C, "const %s grpc_stats_table_%d[%d] = {%s};" % ( tbl[0], i, len(tbl[1]), ','.join('%s' % x for x in tbl[1])) + for histogram, code in zip(inst_map['Histogram'], histo_code): + print >>C, ("void grpc_stats_inc_%s(grpc_exec_ctx *exec_ctx, double value) {%s}") % ( + histogram.name.lower(), + code) + print >>C, "const int grpc_stats_histo_buckets[%d] = {%s};" % ( len(inst_map['Histogram']), ','.join('%s' % x for x in histo_buckets)) print >>C, "const int grpc_stats_histo_start[%d] = {%s};" % ( len(inst_map['Histogram']), ','.join('%s' % x for x in histo_start)) print >>C, "const double *const grpc_stats_histo_bucket_boundaries[%d] = {%s};" % ( len(inst_map['Histogram']), ','.join('grpc_stats_table_%d' % x for x in histo_bucket_boundaries)) + print >>C, "void (*const grpc_stats_inc_histogram[%d])(grpc_exec_ctx *exec_ctx, double x) = {%s};" % ( + len(inst_map['Histogram']), ','.join('grpc_stats_inc_%s' % histogram.name.lower() for histogram in inst_map['Histogram'])) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5ce25dc14a..7326f8cf72 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4018,6 +4018,24 @@ "gpr", "gpr_test_util", "grpc", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "stats_test", + "src": [ + "test/core/debug/stats_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", "grpc++", "grpc_test_util" ], diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 4368a5768e..f77b45839e 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3943,6 +3943,28 @@ "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, + "gtest": true, + "language": "c++", + "name": "stats_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, "gtest": false, "language": "c++", "name": "status_test", |