Merge branch 'stats_histo_ints' into stats_histo
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ecfc8c8..0deab99 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -756,6 +756,7 @@
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)
@@ -12754,6 +12755,47 @@
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
diff --git a/Makefile b/Makefile
index 78451e2..8639c31 100644
--- a/Makefile
+++ b/Makefile
@@ -1170,6 +1170,7 @@
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 @@
$(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 @@
$(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 @@
$(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"
@@ -16699,6 +16704,49 @@
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 00d3429..4539896 100644
--- a/build.yaml
+++ b/build.yaml
@@ -4529,6 +4529,18 @@
- 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 47f482b..8ebfb23 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",
@@ -60,11 +62,11 @@
388125, 498910, 641316, 824370, 1059674, 1362141, 1750943, 2250722,
2893155, 3718960, 4780478, 6144988, 7898976, 10153611, 13051794, 16777216};
const uint8_t grpc_stats_table_1[87] = {
- 1, 1, 3, 3, 4, 6, 6, 8, 8, 9, 11, 11, 12, 14, 14, 15, 17, 17,
- 18, 20, 20, 21, 23, 23, 24, 25, 27, 27, 28, 30, 30, 31, 33, 33, 34, 35,
- 37, 37, 39, 39, 40, 41, 43, 43, 44, 46, 46, 47, 48, 50, 50, 51, 53, 53,
- 55, 55, 56, 57, 59, 59, 60, 62, 62, 63, 64, 66, 66, 67, 69, 69, 71, 71,
- 72, 73, 75, 75, 76, 78, 78, 79, 80, 82, 82, 83, 85, 85, 87};
+ 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10,
+ 11, 12, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 23,
+ 24, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 35,
+ 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46, 47, 47,
+ 48, 49, 50, 50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 57, 58};
const int grpc_stats_table_2[64] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
15, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 49,
@@ -72,14 +74,160 @@
159, 172, 186, 201, 218, 236, 255, 276, 299, 323, 349, 377, 408,
441, 477, 515, 556, 601, 649, 701, 757, 817, 881, 950, 1024};
const uint8_t grpc_stats_table_3[104] = {
- 2, 2, 2, 6, 6, 6, 6, 9, 9, 9, 11, 11, 13, 13, 15, 15, 17, 17,
- 20, 20, 20, 23, 23, 23, 25, 25, 26, 28, 28, 30, 30, 32, 32, 35, 35, 35,
- 37, 37, 40, 40, 40, 41, 43, 43, 44, 46, 46, 48, 48, 50, 50, 52, 52, 55,
- 55, 55, 57, 57, 58, 59, 61, 61, 63, 63, 65, 65, 67, 67, 69, 69, 71, 71,
- 73, 73, 74, 76, 76, 77, 79, 79, 81, 81, 83, 83, 85, 85, 88, 88, 88, 89,
- 90, 92, 92, 93, 95, 95, 97, 97, 99, 99, 101, 101, 104, 104};
+ 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 7, 8, 8, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14,
+ 15, 15, 16, 16, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24,
+ 24, 24, 25, 25, 26, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
+ 34, 34, 35, 36, 36, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 42, 43,
+ 44, 45, 45, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51};
+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 < 4682617712558473216ull) {
+ 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 < 4637300241308057600ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE,
+ grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 48)] +
+ 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 < 4682617712558473216ull) {
+ 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));
+ }
+ }
+}
+void grpc_stats_inc_tcp_read_offer(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_OFFER,
+ (int)_val.dbl);
+ } else {
+ if (_val.uint < 4682617712558473216ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_OFFER,
+ grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_OFFER,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_0, 64));
+ }
+ }
+}
+void grpc_stats_inc_tcp_read_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_READ_IOV_SIZE,
+ (int)_val.dbl);
+ } else {
+ if (_val.uint < 4637300241308057600ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE,
+ grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 48)] +
+ 11);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_2, 64));
+ }
+ }
+}
+void grpc_stats_inc_http2_send_message_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_HTTP2_SEND_MESSAGE_SIZE,
+ (int)_val.dbl);
+ } else {
+ if (_val.uint < 4682617712558473216ull) {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE,
+ grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)] + 4);
+ } else {
+ GRPC_STATS_INC_HISTOGRAM(
+ (exec_ctx), GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE,
+ grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl,
+ grpc_stats_table_0, 64));
+ }
+ }
+}
const int grpc_stats_histo_buckets[6] = {64, 64, 64, 64, 64, 64};
const int grpc_stats_histo_start[6] = {0, 64, 128, 192, 256, 320};
const int *const grpc_stats_histo_bucket_boundaries[6] = {
grpc_stats_table_0, grpc_stats_table_2, grpc_stats_table_0,
grpc_stats_table_0, grpc_stats_table_2, grpc_stats_table_0};
+void (*const grpc_stats_inc_histogram[6])(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, grpc_stats_inc_tcp_read_offer,
+ grpc_stats_inc_tcp_read_iov_size, grpc_stats_inc_http2_send_message_size};
diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h
index 5350264..13bf9d0 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,
@@ -138,157 +139,29 @@
GRPC_STATS_COUNTER_EXECUTOR_WAKEUP_INITIATED)
#define GRPC_STATS_INC_EXECUTOR_QUEUE_DRAINED(exec_ctx) \
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_EXECUTOR_QUEUE_DRAINED)
-#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) >> 48)]); \
- } 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)
-#define GRPC_STATS_INC_TCP_READ_OFFER(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_OFFER, (int)_val.dbl); \
- } else { \
- if (_val.uint < 4715268809856909312ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_OFFER, \
- grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_OFFER, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_0, 64)); \
- } \
- } \
- } while (false)
-#define GRPC_STATS_INC_TCP_READ_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_READ_IOV_SIZE, (int)_val.dbl); \
- } else { \
- if (_val.uint < 4652218415073722368ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE, \
- grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 48)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_2, 64)); \
- } \
- } \
- } while (false)
-#define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_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_HTTP2_SEND_MESSAGE_SIZE, \
- (int)_val.dbl); \
- } else { \
- if (_val.uint < 4715268809856909312ull) { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE, \
- grpc_stats_table_1[((_val.uint - 4617315517961601024ull) >> 50)]); \
- } else { \
- GRPC_STATS_INC_HISTOGRAM( \
- (exec_ctx), GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE, \
- grpc_stats_histo_find_bucket_slow((exec_ctx), _val.dbl, \
- grpc_stats_table_0, 64)); \
- } \
- } \
- } while (false)
-extern const int grpc_stats_table_0[64];
-extern const uint8_t grpc_stats_table_1[87];
-extern const int grpc_stats_table_2[64];
-extern const uint8_t grpc_stats_table_3[104];
+#define GRPC_STATS_INC_TCP_WRITE_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_write_size((exec_ctx), (int)(value))
+void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, int x);
+#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_write_iov_size((exec_ctx), (int)(value))
+void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, int x);
+#define GRPC_STATS_INC_TCP_READ_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_read_size((exec_ctx), (int)(value))
+void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, int x);
+#define GRPC_STATS_INC_TCP_READ_OFFER(exec_ctx, value) \
+ grpc_stats_inc_tcp_read_offer((exec_ctx), (int)(value))
+void grpc_stats_inc_tcp_read_offer(grpc_exec_ctx *exec_ctx, int x);
+#define GRPC_STATS_INC_TCP_READ_IOV_SIZE(exec_ctx, value) \
+ grpc_stats_inc_tcp_read_iov_size((exec_ctx), (int)(value))
+void grpc_stats_inc_tcp_read_iov_size(grpc_exec_ctx *exec_ctx, int x);
+#define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE(exec_ctx, value) \
+ grpc_stats_inc_http2_send_message_size((exec_ctx), (int)(value))
+void grpc_stats_inc_http2_send_message_size(grpc_exec_ctx *exec_ctx, int x);
extern const int grpc_stats_histo_buckets[6];
extern const int grpc_stats_histo_start[6];
extern const int *const grpc_stats_histo_bucket_boundaries[6];
+extern const double *const grpc_stats_histo_bucket_boundaries[6];
+extern void (*const grpc_stats_inc_histogram[6])(grpc_exec_ctx *exec_ctx,
+ int 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 0000000..65ccc7a
--- /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 f33f07c..857c99d 100755
--- a/tools/codegen/core/gen_stats_data.py
+++ b/tools/codegen/core/gen_stats_data.py
@@ -72,11 +72,13 @@
def gen_map_table(mapped_bounds, shift_data):
tbl = []
cur = 0
+ print mapped_bounds
mapped_bounds = [x >> shift_data[0] for x in mapped_bounds]
+ print mapped_bounds
for i in range(0, mapped_bounds[shift_data[1]-1]):
while i > mapped_bounds[cur]:
cur += 1
- tbl.append(mapped_bounds[cur])
+ tbl.append(cur)
return tbl
static_tables = []
@@ -126,34 +128,32 @@
first_nontrivial_code = dbl2u64(first_nontrivial)
code_bounds = [dbl2u64(x) - first_nontrivial_code for x in bounds]
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'
+ #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 = ' 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
@@ -187,6 +187,7 @@
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()):
@@ -218,11 +219,9 @@
"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), (int)(value))" % (
+ histogram.name.upper(), histogram.name.lower())
+ print >>H, "void grpc_stats_inc_%s(grpc_exec_ctx *exec_ctx, int 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]))
@@ -230,6 +229,8 @@
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 int *const grpc_stats_histo_bucket_boundaries[%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, int x);" % len(inst_map['Histogram'])
print >>H
print >>H, "#endif /* GRPC_CORE_LIB_DEBUG_STATS_DATA_H */"
@@ -253,6 +254,14 @@
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] = {" % (
@@ -264,9 +273,16 @@
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 int *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 ecfb96e..186f383 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -4021,6 +4021,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 4368a57..f77b458 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",