From 6ba9302b91f366fb401e0300dd231f7c63208038 Mon Sep 17 00:00:00 2001 From: Anton Kirilov Date: Sat, 11 Jan 2025 21:20:18 +0000 Subject: [PATCH] H2O: Track connection load across the worker threads --- frameworks/C/h2o/src/event_loop.c | 29 +++++++++++++++++++++++++++++ frameworks/C/h2o/src/event_loop.h | 5 +++++ 2 files changed, 34 insertions(+) diff --git a/frameworks/C/h2o/src/event_loop.c b/frameworks/C/h2o/src/event_loop.c index d5e138348de..5e49f246d60 100644 --- a/frameworks/C/h2o/src/event_loop.c +++ b/frameworks/C/h2o/src/event_loop.c @@ -32,13 +32,16 @@ #include #include #include +#include #include #include "error.h" #include "event_loop.h" #include "global_data.h" #include "thread.h" +#include "utility.h" +#define CONN_NUM_SAMPLE_PERIOD 2500 #define DEFAULT_TCP_FASTOPEN_QUEUE_LEN 4096 static void accept_connection(h2o_socket_t *listener, const char *err); @@ -72,6 +75,7 @@ static void accept_connection(h2o_socket_t *listener, const char *err) if (!sock) break; + ctx->event_loop.accepted_conn_num++; ctx->event_loop.conn_num++; sock->on_close.cb = on_close_connection; sock->on_close.data = &ctx->event_loop.conn_num; @@ -277,11 +281,36 @@ static void start_accept_polling(const config_t *config, void event_loop(struct thread_context_t *ctx) { + uint64_t last_sample = 0; + while (!ctx->shutdown || ctx->event_loop.conn_num) { h2o_evloop_run(ctx->event_loop.h2o_ctx.loop, INT32_MAX); process_messages(&ctx->global_thread_data->h2o_receiver, &ctx->event_loop.local_messages); + + const uint64_t now = h2o_now(ctx->event_loop.h2o_ctx.loop); + + if (now - last_sample > CONN_NUM_SAMPLE_PERIOD || last_sample > now) { + const size_t i = ctx->event_loop.conn_num_sample_idx; + + ctx->event_loop.conn_num_sample[i] = ctx->event_loop.conn_num; + ctx->event_loop.conn_num_sample_idx = + (i + 1) % ARRAY_SIZE(ctx->event_loop.conn_num_sample); + last_sample = now; + } } + + flockfile(stdout); + printf("Thread %ld statistics:\nAccepted connections: %zu\nConnection number samples: %zu", + syscall(SYS_gettid), + ctx->event_loop.accepted_conn_num, + *ctx->event_loop.conn_num_sample); + + for (size_t i = 1; i < ARRAY_SIZE(ctx->event_loop.conn_num_sample); i++) + printf(",%zu", ctx->event_loop.conn_num_sample[i]); + + putc_unlocked('\n', stdout); + funlockfile(stdout); } void free_event_loop(event_loop_t *event_loop, h2o_multithread_receiver_t *h2o_receiver) diff --git a/frameworks/C/h2o/src/event_loop.h b/frameworks/C/h2o/src/event_loop.h index cff091154c7..41a1f3b920f 100644 --- a/frameworks/C/h2o/src/event_loop.h +++ b/frameworks/C/h2o/src/event_loop.h @@ -27,6 +27,8 @@ #include "global_data.h" +#define CONN_NUM_SAMPLES 512 + typedef enum { SHUTDOWN, TASK @@ -41,6 +43,9 @@ typedef struct { h2o_accept_ctx_t h2o_accept_ctx; h2o_context_t h2o_ctx; h2o_linklist_t local_messages; + size_t accepted_conn_num; + size_t conn_num_sample[CONN_NUM_SAMPLES]; + size_t conn_num_sample_idx; } event_loop_t; typedef struct {