aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-09-01 16:36:52 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-09-01 16:36:52 -0700
commit56a84848c7b683e6e7fb3bef8b37364f9984cfdb (patch)
tree1b3bdae104ea63334572186ebf192ccb2de08fbb /src
parent40bca8468e91e5e8a9df0b84b30458bf79a3acc3 (diff)
parentda5cd59ed3f383318fb01b1bf461489cc828d453 (diff)
Merge branch 'stats_histo_ints' into stats_histo
Diffstat (limited to 'src')
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c12
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.c4
-rw-r--r--src/core/lib/debug/stats.c6
-rw-r--r--src/core/lib/debug/stats.h2
-rw-r--r--src/core/lib/debug/stats_data.c281
-rw-r--r--src/core/lib/debug/stats_data.h120
-rw-r--r--src/core/lib/debug/stats_data.yaml56
-rw-r--r--src/core/lib/iomgr/combiner.c5
-rw-r--r--src/core/lib/iomgr/executor.c6
-rw-r--r--src/core/lib/iomgr/tcp_posix.c8
-rw-r--r--src/cpp/util/core_stats.cc90
-rw-r--r--src/cpp/util/core_stats.h35
-rw-r--r--src/proto/grpc/core/stats.proto38
-rw-r--r--src/proto/grpc/testing/stats.proto8
14 files changed, 494 insertions, 177 deletions
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 7541bd5c92..3277cefc2d 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -34,6 +34,7 @@
#include "src/core/ext/transport/chttp2/transport/varint.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/compression/stream_compression.h"
+#include "src/core/lib/debug/stats.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/timer.h"
@@ -1258,6 +1259,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
grpc_transport_stream_op_batch_payload *op_payload = op->payload;
grpc_chttp2_transport *t = s->t;
+ GRPC_STATS_INC_HTTP2_OP_BATCHES(exec_ctx);
+
if (GRPC_TRACER_ON(grpc_http_trace)) {
char *str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
@@ -1291,11 +1294,13 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->cancel_stream) {
+ GRPC_STATS_INC_HTTP2_OP_CANCEL(exec_ctx);
grpc_chttp2_cancel_stream(exec_ctx, t, s,
op_payload->cancel_stream.cancel_error);
}
if (op->send_initial_metadata) {
+ GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA(exec_ctx);
GPR_ASSERT(s->send_initial_metadata_finished == NULL);
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
@@ -1373,6 +1378,9 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->send_message) {
+ GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(exec_ctx);
+ GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE(
+ exec_ctx, op->payload->send_message.send_message->length);
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
s->fetching_send_message_finished = add_closure_barrier(op->on_complete);
if (s->write_closed) {
@@ -1410,6 +1418,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->send_trailing_metadata) {
+ GRPC_STATS_INC_HTTP2_OP_SEND_TRAILING_METADATA(exec_ctx);
GPR_ASSERT(s->send_trailing_metadata_finished == NULL);
on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE;
s->send_trailing_metadata_finished = add_closure_barrier(on_complete);
@@ -1459,6 +1468,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->recv_initial_metadata) {
+ GRPC_STATS_INC_HTTP2_OP_RECV_INITIAL_METADATA(exec_ctx);
GPR_ASSERT(s->recv_initial_metadata_ready == NULL);
s->recv_initial_metadata_ready =
op_payload->recv_initial_metadata.recv_initial_metadata_ready;
@@ -1470,6 +1480,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->recv_message) {
+ GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(exec_ctx);
size_t already_received;
GPR_ASSERT(s->recv_message_ready == NULL);
GPR_ASSERT(!s->pending_byte_stream);
@@ -1491,6 +1502,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
}
if (op->recv_trailing_metadata) {
+ GRPC_STATS_INC_HTTP2_OP_RECV_TRAILING_METADATA(exec_ctx);
GPR_ASSERT(s->recv_trailing_metadata_finished == NULL);
s->recv_trailing_metadata_finished = add_closure_barrier(on_complete);
s->recv_trailing_metadata =
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 80eb51ff0d..c16ffaa5ef 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -22,6 +22,7 @@
#include <grpc/support/log.h>
+#include "src/core/lib/debug/stats.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/http2_errors.h"
@@ -116,6 +117,7 @@ static void maybe_initiate_ping(grpc_exec_ctx *exec_ctx,
&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT]);
grpc_slice_buffer_add(&t->outbuf,
grpc_chttp2_ping_create(false, pq->inflight_id));
+ GRPC_STATS_INC_HTTP2_PINGS_SENT(exec_ctx);
t->ping_state.last_ping_sent_time = now;
t->ping_state.pings_before_data_required -=
(t->ping_state.pings_before_data_required != 0);
@@ -171,6 +173,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
grpc_chttp2_stream *s;
+ GRPC_STATS_INC_HTTP2_WRITES_BEGUN(exec_ctx);
+
GPR_TIMER_BEGIN("grpc_chttp2_begin_write", 0);
if (t->dirtied_local_settings && !t->sent_local_settings) {
diff --git a/src/core/lib/debug/stats.c b/src/core/lib/debug/stats.c
index 5079ed2ffa..a65dfe49b1 100644
--- a/src/core/lib/debug/stats.c
+++ b/src/core/lib/debug/stats.c
@@ -63,7 +63,7 @@ void grpc_stats_diff(const grpc_stats_data *b, const grpc_stats_data *a,
}
int grpc_stats_histo_find_bucket_slow(grpc_exec_ctx *exec_ctx, double value,
- const double *table, int table_size) {
+ const int *table, int table_size) {
GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS(exec_ctx);
if (value < 0.0) return 0;
if (value >= table[table_size - 1]) return table_size - 1;
@@ -92,7 +92,7 @@ size_t grpc_stats_histo_count(const grpc_stats_data *stats,
}
static double threshold_for_count_below(const gpr_atm *bucket_counts,
- const double *bucket_boundaries,
+ const int *bucket_boundaries,
int num_buckets, double count_below) {
double count_so_far;
double lower_bound;
@@ -163,7 +163,7 @@ char *grpc_stats_data_as_json(const grpc_stats_data *data) {
gpr_asprintf(&tmp, "], \"%s_bkt\": [", grpc_stats_histogram_name[i]);
gpr_strvec_add(&v, tmp);
for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) {
- gpr_asprintf(&tmp, "%s%lf", j == 0 ? "" : ",",
+ gpr_asprintf(&tmp, "%s%d", j == 0 ? "" : ",",
grpc_stats_histo_bucket_boundaries[i][j]);
gpr_strvec_add(&v, tmp);
}
diff --git a/src/core/lib/debug/stats.h b/src/core/lib/debug/stats.h
index c440ab3b66..9d729c20f4 100644
--- a/src/core/lib/debug/stats.h
+++ b/src/core/lib/debug/stats.h
@@ -51,7 +51,7 @@ void grpc_stats_diff(const grpc_stats_data *b, const grpc_stats_data *a,
grpc_stats_data *c);
char *grpc_stats_data_as_json(const grpc_stats_data *data);
int grpc_stats_histo_find_bucket_slow(grpc_exec_ctx *exec_ctx, double value,
- const double *table, int table_size);
+ const int *table, int table_size);
double grpc_stats_histo_percentile(const grpc_stats_data *data,
grpc_stats_histograms histogram,
double percentile);
diff --git a/src/core/lib/debug/stats_data.c b/src/core/lib/debug/stats_data.c
index eeb1f9460a..8ebfb23283 100644
--- a/src/core/lib/debug/stats_data.c
+++ b/src/core/lib/debug/stats_data.c
@@ -22,151 +22,64 @@
#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",
+ "client_calls_created",
+ "server_calls_created",
+ "syscall_poll",
+ "syscall_wait",
"histogram_slow_lookups",
+ "syscall_write",
+ "syscall_read",
+ "http2_op_batches",
+ "http2_op_cancel",
+ "http2_op_send_initial_metadata",
+ "http2_op_send_message",
+ "http2_op_send_trailing_metadata",
+ "http2_op_recv_initial_metadata",
+ "http2_op_recv_message",
+ "http2_op_recv_trailing_metadata",
+ "http2_pings_sent",
+ "http2_writes_begun",
+ "combiner_locks_initiated",
+ "combiner_locks_scheduled_items",
+ "combiner_locks_scheduled_final_items",
+ "combiner_locks_offloaded",
+ "executor_scheduled_items",
+ "executor_scheduled_to_self",
+ "executor_wakeup_initiated",
+ "executor_queue_drained",
};
const char *grpc_stats_histogram_name[GRPC_STATS_HISTOGRAM_COUNT] = {
"tcp_write_size", "tcp_write_iov_size", "tcp_read_size",
+ "tcp_read_offer", "tcp_read_iov_size", "http2_send_message_size",
};
-const double grpc_stats_table_0[64] = {0,
- 1,
- 2,
- 3,
- 4,
- 5.17974600698,
- 6.70744217421,
- 8.68571170472,
- 11.2474451301,
- 14.5647272503,
- 18.8603969544,
- 24.4230164536,
- 31.6262554885,
- 40.9539926456,
- 53.032819969,
- 68.6741343683,
- 88.9286433193,
- 115.156946285,
- 149.120933174,
- 193.102139541,
- 250.055009057,
- 323.805358672,
- 419.307378404,
- 542.976429747,
- 703.119998467,
- 910.495751121,
- 1179.03418281,
- 1526.77440013,
- 1977.07590065,
- 2560.18775048,
- 3315.28056941,
- 4293.07782286,
- 5559.26317765,
- 7198.89281155,
- 9322.10907382,
- 12071.5393129,
- 15631.8768886,
- 20242.2879738,
- 26212.4775761,
- 33943.4940145,
- 43954.6693961,
- 56918.5058232,
- 73705.8508152,
- 95444.3966128,
- 123594.433061,
- 160046.942783,
- 207250.628202,
- 268376.403469,
- 347530.401059,
- 450029.801797,
- 582760.01722,
- 754637.218056,
- 977207.279236,
- 1265421.37565,
- 1638640.32942,
- 2121935.1758,
- 2747771.31348,
- 3558189.37227,
- 4607629.29828,
- 5966587.36485,
- 7726351.7696,
- 10005134.9318,
- 12956014.428,
- 16777216.0};
+const int grpc_stats_table_0[64] = {
+ 0, 1, 2, 3, 4, 6, 8, 11,
+ 15, 20, 26, 34, 44, 57, 74, 96,
+ 124, 160, 206, 265, 341, 439, 565, 727,
+ 935, 1202, 1546, 1988, 2556, 3286, 4225, 5432,
+ 6983, 8977, 11540, 14834, 19069, 24513, 31510, 40505,
+ 52067, 66929, 86033, 110590, 142157, 182734, 234893, 301940,
+ 388125, 498910, 641316, 824370, 1059674, 1362141, 1750943, 2250722,
+ 2893155, 3718960, 4780478, 6144988, 7898976, 10153611, 13051794, 16777216};
const uint8_t grpc_stats_table_1[87] = {
- 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 12,
- 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, 23, 24,
- 24, 25, 26, 26, 27, 28, 28, 29, 30, 31, 31, 32, 33, 33, 34, 34, 35, 36,
- 37, 37, 38, 39, 39, 40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 47, 47, 48,
- 49, 49, 50, 50, 51, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58};
-const double grpc_stats_table_2[64] = {0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12.0020736244,
- 13.0954337532,
- 14.2883963681,
- 15.5900350167,
- 17.0102498252,
- 18.5598427974,
- 20.2505999737,
- 22.0953810747,
- 24.1082173107,
- 26.3044181014,
- 28.7006875181,
- 31.315251333,
- 34.1679956422,
- 37.2806181177,
- 40.6767930374,
- 44.3823513489,
- 48.4254771375,
- 52.8369219909,
- 57.6502388927,
- 62.902037423,
- 68.6322622068,
- 74.8844967285,
- 81.7062948236,
- 89.1495423679,
- 97.2708519163,
- 106.131993291,
- 115.800363399,
- 126.34949884,
- 137.859635225,
- 150.418317437,
- 164.121065485,
- 179.072101023,
- 195.38514005,
- 213.184257818,
- 232.604832535,
- 253.794575043,
- 276.914652285,
- 302.140913126,
- 329.665225843,
- 359.696937452,
- 392.464465978,
- 428.217037783,
- 467.226583154,
- 509.78980457,
- 556.230433401,
- 606.901692163,
- 662.1889811,
- 722.512809492,
- 788.331994007,
- 860.147148411,
- 938.504491184,
- 1024.0};
-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, 51};
+ 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,
+ 54, 59, 64, 70, 76, 83, 90, 98, 106, 115, 125, 136, 147,
+ 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] = {
+ 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;
@@ -201,10 +114,10 @@ void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double value) {
GRPC_STATS_INC_HISTOGRAM(
(exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE, (int)_val.dbl);
} else {
- if (_val.uint < 4651655465120301056ull) {
+ if (_val.uint < 4637300241308057600ull) {
GRPC_STATS_INC_HISTOGRAM(
(exec_ctx), GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE,
- grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 49)] +
+ grpc_stats_table_3[((_val.uint - 4622945017495814144ull) >> 48)] +
11);
} else {
GRPC_STATS_INC_HISTOGRAM(
@@ -237,10 +150,84 @@ void grpc_stats_inc_tcp_read_size(grpc_exec_ctx *exec_ctx, double value) {
}
}
}
-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] = {
+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[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};
+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 4fff769450..13bf9d0c8e 100644
--- a/src/core/lib/debug/stats_data.h
+++ b/src/core/lib/debug/stats_data.h
@@ -27,11 +27,29 @@
typedef enum {
GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED,
GRPC_STATS_COUNTER_SERVER_CALLS_CREATED,
- GRPC_STATS_COUNTER_SYSCALL_WRITE,
- GRPC_STATS_COUNTER_SYSCALL_READ,
GRPC_STATS_COUNTER_SYSCALL_POLL,
GRPC_STATS_COUNTER_SYSCALL_WAIT,
GRPC_STATS_COUNTER_HISTOGRAM_SLOW_LOOKUPS,
+ GRPC_STATS_COUNTER_SYSCALL_WRITE,
+ GRPC_STATS_COUNTER_SYSCALL_READ,
+ GRPC_STATS_COUNTER_HTTP2_OP_BATCHES,
+ GRPC_STATS_COUNTER_HTTP2_OP_CANCEL,
+ GRPC_STATS_COUNTER_HTTP2_OP_SEND_INITIAL_METADATA,
+ GRPC_STATS_COUNTER_HTTP2_OP_SEND_MESSAGE,
+ GRPC_STATS_COUNTER_HTTP2_OP_SEND_TRAILING_METADATA,
+ GRPC_STATS_COUNTER_HTTP2_OP_RECV_INITIAL_METADATA,
+ GRPC_STATS_COUNTER_HTTP2_OP_RECV_MESSAGE,
+ GRPC_STATS_COUNTER_HTTP2_OP_RECV_TRAILING_METADATA,
+ GRPC_STATS_COUNTER_HTTP2_PINGS_SENT,
+ GRPC_STATS_COUNTER_HTTP2_WRITES_BEGUN,
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_INITIATED,
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_ITEMS,
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS,
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_OFFLOADED,
+ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_ITEMS,
+ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_TO_SELF,
+ GRPC_STATS_COUNTER_EXECUTOR_WAKEUP_INITIATED,
+ GRPC_STATS_COUNTER_EXECUTOR_QUEUE_DRAINED,
GRPC_STATS_COUNTER_COUNT
} grpc_stats_counters;
extern const char *grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT];
@@ -39,6 +57,9 @@ typedef enum {
GRPC_STATS_HISTOGRAM_TCP_WRITE_SIZE,
GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE,
GRPC_STATS_HISTOGRAM_TCP_READ_SIZE,
+ GRPC_STATS_HISTOGRAM_TCP_READ_OFFER,
+ GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE,
+ GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE,
GRPC_STATS_HISTOGRAM_COUNT
} grpc_stats_histograms;
extern const char *grpc_stats_histogram_name[GRPC_STATS_HISTOGRAM_COUNT];
@@ -49,35 +70,98 @@ typedef enum {
GRPC_STATS_HISTOGRAM_TCP_WRITE_IOV_SIZE_BUCKETS = 64,
GRPC_STATS_HISTOGRAM_TCP_READ_SIZE_FIRST_SLOT = 128,
GRPC_STATS_HISTOGRAM_TCP_READ_SIZE_BUCKETS = 64,
- GRPC_STATS_HISTOGRAM_BUCKETS = 192
+ GRPC_STATS_HISTOGRAM_TCP_READ_OFFER_FIRST_SLOT = 192,
+ GRPC_STATS_HISTOGRAM_TCP_READ_OFFER_BUCKETS = 64,
+ GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE_FIRST_SLOT = 256,
+ GRPC_STATS_HISTOGRAM_TCP_READ_IOV_SIZE_BUCKETS = 64,
+ GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE_FIRST_SLOT = 320,
+ GRPC_STATS_HISTOGRAM_HTTP2_SEND_MESSAGE_SIZE_BUCKETS = 64,
+ GRPC_STATS_HISTOGRAM_BUCKETS = 384
} grpc_stats_histogram_constants;
#define GRPC_STATS_INC_CLIENT_CALLS_CREATED(exec_ctx) \
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED)
#define GRPC_STATS_INC_SERVER_CALLS_CREATED(exec_ctx) \
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SERVER_CALLS_CREATED)
-#define GRPC_STATS_INC_SYSCALL_WRITE(exec_ctx) \
- GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_WRITE)
-#define GRPC_STATS_INC_SYSCALL_READ(exec_ctx) \
- GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_READ)
#define GRPC_STATS_INC_SYSCALL_POLL(exec_ctx) \
GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_POLL)
#define GRPC_STATS_INC_SYSCALL_WAIT(exec_ctx) \
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_SYSCALL_WRITE(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_WRITE)
+#define GRPC_STATS_INC_SYSCALL_READ(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_SYSCALL_READ)
+#define GRPC_STATS_INC_HTTP2_OP_BATCHES(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_OP_BATCHES)
+#define GRPC_STATS_INC_HTTP2_OP_CANCEL(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_OP_CANCEL)
+#define GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_HTTP2_OP_SEND_INITIAL_METADATA)
+#define GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_OP_SEND_MESSAGE)
+#define GRPC_STATS_INC_HTTP2_OP_SEND_TRAILING_METADATA(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_HTTP2_OP_SEND_TRAILING_METADATA)
+#define GRPC_STATS_INC_HTTP2_OP_RECV_INITIAL_METADATA(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_HTTP2_OP_RECV_INITIAL_METADATA)
+#define GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_OP_RECV_MESSAGE)
+#define GRPC_STATS_INC_HTTP2_OP_RECV_TRAILING_METADATA(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_HTTP2_OP_RECV_TRAILING_METADATA)
+#define GRPC_STATS_INC_HTTP2_PINGS_SENT(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_PINGS_SENT)
+#define GRPC_STATS_INC_HTTP2_WRITES_BEGUN(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), GRPC_STATS_COUNTER_HTTP2_WRITES_BEGUN)
+#define GRPC_STATS_INC_COMBINER_LOCKS_INITIATED(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_INITIATED)
+#define GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_ITEMS(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_ITEMS)
+#define GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS(exec_ctx) \
+ GRPC_STATS_INC_COUNTER( \
+ (exec_ctx), GRPC_STATS_COUNTER_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS)
+#define GRPC_STATS_INC_COMBINER_LOCKS_OFFLOADED(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_COMBINER_LOCKS_OFFLOADED)
+#define GRPC_STATS_INC_EXECUTOR_SCHEDULED_ITEMS(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_ITEMS)
+#define GRPC_STATS_INC_EXECUTOR_SCHEDULED_TO_SELF(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ GRPC_STATS_COUNTER_EXECUTOR_SCHEDULED_TO_SELF)
+#define GRPC_STATS_INC_EXECUTOR_WAKEUP_INITIATED(exec_ctx) \
+ GRPC_STATS_INC_COUNTER((exec_ctx), \
+ 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) \
- grpc_stats_inc_tcp_write_size((exec_ctx), (double)(value))
-void grpc_stats_inc_tcp_write_size(grpc_exec_ctx *exec_ctx, double x);
+ 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), (double)(value))
-void grpc_stats_inc_tcp_write_iov_size(grpc_exec_ctx *exec_ctx, double x);
+ 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), (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);
+ 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/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml
index b8d5f71991..a0d042a688 100644
--- a/src/core/lib/debug/stats_data.yaml
+++ b/src/core/lib/debug/stats_data.yaml
@@ -1,13 +1,31 @@
-#Stats data declaration
-#use tools / codegen / core / gen_stats_data.py to turn this into stats_data.h
+# 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.
+# Stats data declaration
+# use tools / codegen / core / gen_stats_data.py to turn this into stats_data.h
+
+# overall
- counter: client_calls_created
- counter: server_calls_created
-- counter: syscall_write
-- counter: syscall_read
+# polling
- counter: syscall_poll
- counter: syscall_wait
+# stats system
- counter: histogram_slow_lookups
+# tcp
+- counter: syscall_write
+- counter: syscall_read
- histogram: tcp_write_size
max: 16777216 # 16 meg max write tracked
buckets: 64
@@ -17,3 +35,33 @@
- histogram: tcp_read_size
max: 16777216
buckets: 64
+- histogram: tcp_read_offer
+ max: 16777216
+ buckets: 64
+- histogram: tcp_read_iov_size
+ max: 1024
+ buckets: 64
+# chttp2
+- counter: http2_op_batches
+- counter: http2_op_cancel
+- counter: http2_op_send_initial_metadata
+- counter: http2_op_send_message
+- counter: http2_op_send_trailing_metadata
+- counter: http2_op_recv_initial_metadata
+- counter: http2_op_recv_message
+- counter: http2_op_recv_trailing_metadata
+- histogram: http2_send_message_size
+ max: 16777216
+ buckets: 64
+- counter: http2_pings_sent
+- counter: http2_writes_begun
+# combiner locks
+- counter: combiner_locks_initiated
+- counter: combiner_locks_scheduled_items
+- counter: combiner_locks_scheduled_final_items
+- counter: combiner_locks_offloaded
+# executor
+- counter: executor_scheduled_items
+- counter: executor_scheduled_to_self
+- counter: executor_wakeup_initiated
+- counter: executor_queue_drained
diff --git a/src/core/lib/iomgr/combiner.c b/src/core/lib/iomgr/combiner.c
index 9b66987b68..4c1503bddb 100644
--- a/src/core/lib/iomgr/combiner.c
+++ b/src/core/lib/iomgr/combiner.c
@@ -24,6 +24,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/debug/stats.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/profiling/timers.h"
@@ -153,6 +154,7 @@ static void push_first_on_exec_ctx(grpc_exec_ctx *exec_ctx,
static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
grpc_error *error) {
+ GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_ITEMS(exec_ctx);
GPR_TIMER_BEGIN("combiner.execute", 0);
grpc_combiner *lock = COMBINER_FROM_CLOSURE_SCHEDULER(cl, scheduler);
gpr_atm last = gpr_atm_full_fetch_add(&lock->state, STATE_ELEM_COUNT_LOW_BIT);
@@ -160,6 +162,7 @@ static void combiner_exec(grpc_exec_ctx *exec_ctx, grpc_closure *cl,
"C:%p grpc_combiner_execute c=%p last=%" PRIdPTR,
lock, cl, last));
if (last == 1) {
+ GRPC_STATS_INC_COMBINER_LOCKS_INITIATED(exec_ctx);
gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null,
(gpr_atm)exec_ctx);
// first element on this list: add it to the list of combiner locks
@@ -195,6 +198,7 @@ static void offload(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
}
static void queue_offload(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
+ GRPC_STATS_INC_COMBINER_LOCKS_OFFLOADED(exec_ctx);
move_next(exec_ctx);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG, "C:%p queue_offload", lock));
GRPC_CLOSURE_SCHED(exec_ctx, &lock->offload, GRPC_ERROR_NONE);
@@ -325,6 +329,7 @@ static void enqueue_finally(grpc_exec_ctx *exec_ctx, void *closure,
static void combiner_finally_exec(grpc_exec_ctx *exec_ctx,
grpc_closure *closure, grpc_error *error) {
+ GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS(exec_ctx);
grpc_combiner *lock =
COMBINER_FROM_CLOSURE_SCHEDULER(closure, finally_scheduler);
GRPC_COMBINER_TRACE(gpr_log(GPR_DEBUG,
diff --git a/src/core/lib/iomgr/executor.c b/src/core/lib/iomgr/executor.c
index 7621a7fe75..dd5cb2a64e 100644
--- a/src/core/lib/iomgr/executor.c
+++ b/src/core/lib/iomgr/executor.c
@@ -28,6 +28,7 @@
#include <grpc/support/tls.h>
#include <grpc/support/useful.h>
+#include "src/core/lib/debug/stats.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/spinlock.h"
@@ -145,6 +146,7 @@ static void executor_thread(void *arg) {
gpr_mu_unlock(&ts->mu);
break;
}
+ GRPC_STATS_INC_EXECUTOR_QUEUE_DRAINED(&exec_ctx);
grpc_closure_list exec = ts->elems;
ts->elems = (grpc_closure_list)GRPC_CLOSURE_LIST_INIT;
gpr_mu_unlock(&ts->mu);
@@ -158,6 +160,7 @@ static void executor_thread(void *arg) {
static void executor_push(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
grpc_error *error) {
size_t cur_thread_count = (size_t)gpr_atm_no_barrier_load(&g_cur_threads);
+ GRPC_STATS_INC_EXECUTOR_SCHEDULED_ITEMS(exec_ctx);
if (cur_thread_count == 0) {
grpc_closure_list_append(&exec_ctx->closure_list, closure, error);
return;
@@ -165,9 +168,12 @@ static void executor_push(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
thread_state *ts = (thread_state *)gpr_tls_get(&g_this_thread_state);
if (ts == NULL) {
ts = &g_thread_state[GPR_HASH_POINTER(exec_ctx, cur_thread_count)];
+ } else {
+ GRPC_STATS_INC_EXECUTOR_SCHEDULED_TO_SELF(exec_ctx);
}
gpr_mu_lock(&ts->mu);
if (grpc_closure_list_empty(ts->elems)) {
+ GRPC_STATS_INC_EXECUTOR_WAKEUP_INITIATED(exec_ctx);
gpr_cv_signal(&ts->cv);
}
grpc_closure_list_append(&ts->elems, closure, error);
diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c
index ccf328ec1c..793147f30a 100644
--- a/src/core/lib/iomgr/tcp_posix.c
+++ b/src/core/lib/iomgr/tcp_posix.c
@@ -67,7 +67,6 @@ typedef struct {
grpc_fd *em_fd;
int fd;
bool finished_edge;
- msg_iovlen_type iov_size; /* Number of slices to allocate per read attempt */
double target_length;
double bytes_read_this_round;
gpr_refcount refcount;
@@ -240,7 +239,6 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
size_t i;
GPR_ASSERT(!tcp->finished_edge);
- GPR_ASSERT(tcp->iov_size <= MAX_READ_IOVEC);
GPR_ASSERT(tcp->incoming_buffer->count <= MAX_READ_IOVEC);
GPR_TIMER_BEGIN("tcp_continue_read", 0);
@@ -252,11 +250,14 @@ static void tcp_do_read(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = iov;
- msg.msg_iovlen = tcp->iov_size;
+ msg.msg_iovlen = tcp->incoming_buffer->count;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
+ GRPC_STATS_INC_TCP_READ_OFFER(exec_ctx, tcp->incoming_buffer->length);
+ GRPC_STATS_INC_TCP_READ_IOV_SIZE(exec_ctx, tcp->incoming_buffer->count);
+
GPR_TIMER_BEGIN("recvmsg", 0);
do {
GRPC_STATS_INC_SYSCALL_READ(exec_ctx);
@@ -625,7 +626,6 @@ grpc_endpoint *grpc_tcp_create(grpc_exec_ctx *exec_ctx, grpc_fd *em_fd,
tcp->min_read_chunk_size = tcp_min_read_chunk_size;
tcp->max_read_chunk_size = tcp_max_read_chunk_size;
tcp->bytes_read_this_round = 0;
- tcp->iov_size = 1;
tcp->finished_edge = true;
/* paired with unref in grpc_tcp_destroy */
gpr_ref_init(&tcp->refcount, 1);
diff --git a/src/cpp/util/core_stats.cc b/src/cpp/util/core_stats.cc
new file mode 100644
index 0000000000..edf0b1bb67
--- /dev/null
+++ b/src/cpp/util/core_stats.cc
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "src/cpp/util/core_stats.h"
+
+#include <grpc/support/log.h>
+
+using grpc::core::Bucket;
+using grpc::core::Histogram;
+using grpc::core::Metric;
+using grpc::core::Stats;
+
+namespace grpc {
+
+void CoreStatsToProto(const grpc_stats_data& core, Stats* proto) {
+ for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
+ Metric* m = proto->add_metrics();
+ m->set_name(grpc_stats_counter_name[i]);
+ m->set_count(core.counters[i]);
+ }
+ for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
+ Metric* m = proto->add_metrics();
+ m->set_name(grpc_stats_histogram_name[i]);
+ Histogram* h = m->mutable_histogram();
+ for (int j = 0; j < grpc_stats_histo_buckets[i]; j++) {
+ Bucket* b = h->add_buckets();
+ b->set_start(grpc_stats_histo_bucket_boundaries[i][j]);
+ b->set_count(core.histograms[grpc_stats_histo_start[i] + j]);
+ }
+ }
+}
+
+void ProtoToCoreStats(const grpc::core::Stats& proto, grpc_stats_data* core) {
+ memset(core, 0, sizeof(*core));
+ for (const auto& m : proto.metrics()) {
+ switch (m.value_case()) {
+ case Metric::VALUE_NOT_SET:
+ break;
+ case Metric::kCount:
+ for (int i = 0; i < GRPC_STATS_COUNTER_COUNT; i++) {
+ if (m.name() == grpc_stats_counter_name[i]) {
+ core->counters[i] = m.count();
+ break;
+ }
+ }
+ break;
+ case Metric::kHistogram:
+ for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
+ if (m.name() == grpc_stats_histogram_name[i]) {
+ const auto& h = m.histogram();
+ bool valid = true;
+ if (grpc_stats_histo_buckets[i] != h.buckets_size()) valid = false;
+ for (int j = 0; valid && j < h.buckets_size(); j++) {
+ if (grpc_stats_histo_bucket_boundaries[i][j] !=
+ h.buckets(j).start()) {
+ valid = false;
+ }
+ }
+ if (!valid) {
+ gpr_log(GPR_ERROR,
+ "Found histogram %s but shape is different from proto",
+ m.name().c_str());
+ }
+ for (int j = 0; valid && j < h.buckets_size(); j++) {
+ core->histograms[grpc_stats_histo_start[i] + j] =
+ h.buckets(j).count();
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+} // namespace grpc
diff --git a/src/cpp/util/core_stats.h b/src/cpp/util/core_stats.h
new file mode 100644
index 0000000000..00e38bf266
--- /dev/null
+++ b/src/cpp/util/core_stats.h
@@ -0,0 +1,35 @@
+/*
+ *
+ * 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_INTERNAL_CPP_UTIL_CORE_STATS_H
+#define GRPC_INTERNAL_CPP_UTIL_CORE_STATS_H
+
+#include "src/proto/grpc/core/stats.pb.h"
+
+extern "C" {
+#include "src/core/lib/debug/stats.h"
+}
+
+namespace grpc {
+
+void CoreStatsToProto(const grpc_stats_data& core, grpc::core::Stats* proto);
+void ProtoToCoreStats(const grpc::core::Stats& proto, grpc_stats_data* core);
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_UTIL_CORE_STATS_H
diff --git a/src/proto/grpc/core/stats.proto b/src/proto/grpc/core/stats.proto
new file mode 100644
index 0000000000..ac181b0439
--- /dev/null
+++ b/src/proto/grpc/core/stats.proto
@@ -0,0 +1,38 @@
+// 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.
+
+syntax = "proto3";
+
+package grpc.core;
+
+message Bucket {
+ double start = 1;
+ uint64 count = 2;
+}
+
+message Histogram {
+ repeated Bucket buckets = 1;
+}
+
+message Metric {
+ string name = 1;
+ oneof value {
+ uint64 count = 10;
+ Histogram histogram = 11;
+ }
+}
+
+message Stats {
+ repeated Metric metrics = 1;
+}
diff --git a/src/proto/grpc/testing/stats.proto b/src/proto/grpc/testing/stats.proto
index c738c4f895..a0f84ddbce 100644
--- a/src/proto/grpc/testing/stats.proto
+++ b/src/proto/grpc/testing/stats.proto
@@ -16,6 +16,8 @@ syntax = "proto3";
package grpc.testing;
+import "src/proto/grpc/core/stats.proto";
+
message ServerStats {
// wall clock time change in seconds since last reset
double time_elapsed = 1;
@@ -35,6 +37,9 @@ message ServerStats {
// Number of polls called inside completion queue
uint64 cq_poll_count = 6;
+
+ // Core library stats
+ grpc.core.Stats core_stats = 7;
}
// Histogram params based on grpc/support/histogram.c
@@ -72,4 +77,7 @@ message ClientStats {
// Number of polls called inside completion queue
uint64 cq_poll_count = 6;
+
+ // Core library stats
+ grpc.core.Stats core_stats = 7;
}