MEDIUM: buffers: implement b_adv() to advance a buffer's pointer
This is more convenient and efficient than buf->p = b_ptr(buf, n);
It simply advances the buffer's pointer by <n> and trasfers that
amount of bytes from <in> to <out>. The BF_OUT_EMPTY flag is updated
accordingly.
A few occurrences of such computations in buffers.c and stream_sock.c
were updated to use b_adv(), which resulted in a small code shrink.
diff --git a/include/proto/buffers.h b/include/proto/buffers.h
index 5caff85..f82e461 100644
--- a/include/proto/buffers.h
+++ b/include/proto/buffers.h
@@ -242,6 +242,19 @@
return right - left;
}
+/* Advances the buffer by <adv> bytes, which means that the buffer
+ * pointer advances, and that as many bytes from in are transferred
+ * to out. The caller is responsible for ensuring that adv is always
+ * smaller than or equal to b->i. The BF_OUT_EMPTY flag is updated.
+ */
+static inline void b_adv(struct buffer *b, unsigned int adv)
+{
+ b->i -= adv;
+ b->o += adv;
+ if (b->o)
+ b->flags &= ~BF_OUT_EMPTY;
+ b->p = b_ptr(b, adv);
+}
/* Return the amount of bytes that can be written into the buffer at once,
* excluding the amount of reserved space passed in <res>, which is
diff --git a/src/buffers.c b/src/buffers.c
index 40aa57a..2bd24a8 100644
--- a/src/buffers.c
+++ b/src/buffers.c
@@ -42,29 +42,26 @@
{
unsigned int new_forward;
unsigned int forwarded;
+ unsigned int bytes32;
- if (!bytes)
- return 0;
- if (bytes <= (unsigned long long)buf->i) {
- buf->p = b_ptr(buf, (unsigned int)bytes);
- buf->o += bytes;
- buf->i -= bytes;
- buf->flags &= ~BF_OUT_EMPTY;
- return bytes;
+ bytes32 = bytes;
+
+ /* hint: avoid comparisons on long long for the fast case, since if the
+ * length does not fit in an unsigned it, it will never be forwarded at
+ * once anyway.
+ */
+ if (bytes <= ~0U) {
+ if (bytes32 <= buf->i) {
+ /* OK this amount of bytes might be forwarded at once */
+ if (!bytes32)
+ return 0;
+ b_adv(buf, bytes32);
+ return bytes;
+ }
}
forwarded = buf->i;
- buf->p = bi_end(buf);
- buf->o += forwarded;
- buf->i = 0;
-
- if (buf->o)
- buf->flags &= ~BF_OUT_EMPTY;
-
- if (buf->o < buffer_max_len(buf))
- buf->flags &= ~BF_FULL;
- else
- buf->flags |= BF_FULL;
+ b_adv(buf, buf->i);
/* Note: the case below is the only case where we may return
* a byte count that does not fit into a 32-bit number.
@@ -211,10 +208,7 @@
fwd = buf->to_forward;
buf->to_forward -= fwd;
}
- buf->o += fwd;
- buf->i -= fwd;
- buf->p = b_ptr(buf, fwd);
- buf->flags &= ~BF_OUT_EMPTY;
+ b_adv(buf, fwd);
}
buf->flags &= ~BF_FULL;
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 038e8c8..575e24c 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -309,10 +309,7 @@
fwd = b->to_forward;
b->to_forward -= fwd;
}
- b->o += fwd;
- b->i -= fwd;
- b->p = b_ptr(b, fwd);
- b->flags &= ~BF_OUT_EMPTY;
+ b_adv(b, fwd);
}
if (fdtab[fd].state == FD_STCONN)