From 0bc3493d2c15fbc710645c3ad37fe266de278915 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 28 Mar 2011 16:25:58 +0200 Subject: [PATCH] [OPTIM] buffers: uninline buffer_forward() Since the latest additions to buffer_forward(), it became too large for inlining, so let's uninline it. The code size drops by 3kB. Should be backported to 1.4 too. --- include/proto/buffers.h | 58 +---------------------------------------- src/buffers.c | 56 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/include/proto/buffers.h b/include/proto/buffers.h index 2388b15856..af470baa95 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -50,6 +50,7 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len); void buffer_dump(FILE *o, struct buffer *b, int from, int to); void buffer_bounce_realign(struct buffer *buf); +unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes); /* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */ static inline void buffer_init(struct buffer *buf) @@ -110,63 +111,6 @@ static inline void buffer_check_timeouts(struct buffer *b) b->flags |= BF_ANA_TIMEOUT; } -/* Schedule up to more bytes to be forwarded by the buffer without notifying - * the task. Any pending data in the buffer is scheduled to be sent as well, - * in the limit of the number of bytes to forward. This must be the only method - * to use to schedule bytes to be sent. If the requested number is too large, it - * is automatically adjusted. The number of bytes taken into account is returned. - * Directly touching ->to_forward will cause lockups when send_max goes down to - * zero if nobody is ready to push the remaining data. - */ -static inline unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes) -{ - unsigned int data_left; - unsigned int new_forward; - - if (!bytes) - return 0; - data_left = buf->l - buf->send_max; - if (bytes <= (unsigned long long)data_left) { - buf->send_max += bytes; - buf->flags &= ~BF_OUT_EMPTY; - return bytes; - } - - buf->send_max += data_left; - if (buf->send_max) - buf->flags &= ~BF_OUT_EMPTY; - - if (buf->l < buffer_max_len(buf)) - buf->flags &= ~BF_FULL; - else - buf->flags |= BF_FULL; - - if (likely(bytes == BUF_INFINITE_FORWARD)) { - buf->to_forward = bytes; - return bytes; - } - - /* Note: the case below is the only case where we may return - * a byte count that does not fit into a 32-bit number. - */ - if (likely(buf->to_forward == BUF_INFINITE_FORWARD)) - return bytes; - - new_forward = buf->to_forward + bytes - data_left; - bytes = data_left; /* at least those bytes were scheduled */ - - if (new_forward <= buf->to_forward) { - /* integer overflow detected, let's assume no more than 2G at once */ - new_forward = MID_RANGE(new_forward); - } - - if (new_forward > buf->to_forward) { - bytes += new_forward - buf->to_forward; - buf->to_forward = new_forward; - } - return bytes; -} - /* Schedule all remaining buffer data to be sent. send_max is not touched if it * already covers those data. That permits doing a flush even after a forward, * although not recommended. diff --git a/src/buffers.c b/src/buffers.c index 1572a37cc5..44b3f7d3bd 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -30,6 +30,62 @@ int init_buffer() return pool2_buffer != NULL; } +/* Schedule up to more bytes to be forwarded by the buffer without notifying + * the task. Any pending data in the buffer is scheduled to be sent as well, + * in the limit of the number of bytes to forward. This must be the only method + * to use to schedule bytes to be sent. If the requested number is too large, it + * is automatically adjusted. The number of bytes taken into account is returned. + * Directly touching ->to_forward will cause lockups when send_max goes down to + * zero if nobody is ready to push the remaining data. + */ +unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes) +{ + unsigned int data_left; + unsigned int new_forward; + + if (!bytes) + return 0; + data_left = buf->l - buf->send_max; + if (bytes <= (unsigned long long)data_left) { + buf->send_max += bytes; + buf->flags &= ~BF_OUT_EMPTY; + return bytes; + } + + buf->send_max += data_left; + if (buf->send_max) + buf->flags &= ~BF_OUT_EMPTY; + + if (buf->l < buffer_max_len(buf)) + buf->flags &= ~BF_FULL; + else + buf->flags |= BF_FULL; + + if (likely(bytes == BUF_INFINITE_FORWARD)) { + buf->to_forward = bytes; + return bytes; + } + + /* Note: the case below is the only case where we may return + * a byte count that does not fit into a 32-bit number. + */ + if (likely(buf->to_forward == BUF_INFINITE_FORWARD)) + return bytes; + + new_forward = buf->to_forward + bytes - data_left; + bytes = data_left; /* at least those bytes were scheduled */ + + if (new_forward <= buf->to_forward) { + /* integer overflow detected, let's assume no more than 2G at once */ + new_forward = MID_RANGE(new_forward); + } + + if (new_forward > buf->to_forward) { + bytes += new_forward - buf->to_forward; + buf->to_forward = new_forward; + } + return bytes; +} /* writes bytes from message to buffer . Returns -1 in case of * success, -2 if the message is larger than the buffer size, or the number of