From 4e33d8677a17c40dd77488ba317cbf5f3431869c Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 11 Oct 2009 23:35:10 +0200 Subject: [PATCH] [OPTIM] stats: check free space before trying to print This alone makes a typical HTML stats dump consume 10% CPU less, because we avoid doing complex printf calls to drop them later. Only a few common cases have been checked, those which are very likely to run for nothing. --- include/proto/buffers.h | 8 ++++++++ src/dumpstats.c | 15 ++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/proto/buffers.h b/include/proto/buffers.h index 801ea1a1d1..6f10553b0e 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -288,6 +288,14 @@ static inline int buffer_contig_space(struct buffer *buf) return ret; } +/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */ +static inline int buffer_almost_full(struct buffer *buf) +{ + if (buffer_contig_space(buf) < buf->size / 4) + return 1; + return 0; +} + /* * Return the max amount of bytes that can be read from the buffer at once. * Note that this may be lower than the actual buffer length when the data diff --git a/src/dumpstats.c b/src/dumpstats.c index 6d42b41279..5e7312f671 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -540,6 +540,12 @@ void stats_io_handler(struct stream_interface *si) break; } else if (si->st0 == STAT_CLI_GETREQ) { + /* ensure we have some output room left in the event we + * would want to return some info right after parsing. + */ + if (buffer_almost_full(si->ib)) + break; + reql = buffer_si_peekline(si->ob, trash, sizeof(trash)); if (reql <= 0) { /* closed or EOL not found */ if (reql == 0) @@ -1121,6 +1127,8 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri) case DATA_ST_LIST: /* dump proxies */ while (s->data_ctx.stats.px) { + if (buffer_almost_full(rep)) + return 0; px = s->data_ctx.stats.px; /* skip the disabled proxies and non-networked ones */ if (px->state != PR_STSTOPPED && (px->cap & (PR_CAP_FE | PR_CAP_BE))) @@ -1329,6 +1337,9 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri) case DATA_ST_PX_LI: /* stats.l has been initialized above */ for (; s->data_ctx.stats.l != NULL; s->data_ctx.stats.l = l->next) { + if (buffer_almost_full(rep)) + return 0; + l = s->data_ctx.stats.l; if (!l->counters) continue; @@ -1418,9 +1429,11 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri) case DATA_ST_PX_SV: /* stats.sv has been initialized above */ for (; s->data_ctx.stats.sv != NULL; s->data_ctx.stats.sv = sv->next) { - int sv_state; /* 0=DOWN, 1=going up, 2=going down, 3=UP, 4,5=NOLB, 6=unchecked */ + if (buffer_almost_full(rep)) + return 0; + sv = s->data_ctx.stats.sv; if (s->data_ctx.stats.flags & STAT_BOUND) { -- 2.47.2