From: Willy Tarreau Date: Fri, 20 Jul 2018 16:58:51 +0000 (+0200) Subject: MEDIUM: buffers: make b_xfer() automatically swap buffers when possible X-Git-Tag: v1.9-dev1~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7999bfbfd3fd02dcc870e58e738897aa7f89bbe5;p=thirdparty%2Fhaproxy.git MEDIUM: buffers: make b_xfer() automatically swap buffers when possible Whenever it's possible to avoid a copy, b_xfer() will simply swap the buffer's heads without touching the data. This has brought the performance back from 140 kH/s to 202 kH/s on the test case. --- diff --git a/include/common/buf.h b/include/common/buf.h index e72de911ab..6d46111125 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -517,7 +517,9 @@ static inline size_t b_putblk(struct buffer *b, const char *blk, size_t len) /* b_xfer() : transfers at most bytes from buffer to buffer * and returns the number of bytes copied. The bytes are removed from and * added to . The caller is responsible for ensuring that is not - * larger than b_room(dst). + * larger than b_room(dst). Whenever possible (if the destination is empty and + * at least as much as the source was requested), the buffers are simply + * swapped instead of copied. */ static inline size_t b_xfer(struct buffer *dst, struct buffer *src, size_t count) { @@ -533,6 +535,13 @@ static inline size_t b_xfer(struct buffer *dst, struct buffer *src, size_t count if (ret > count) ret = count; + else if (!b_data(dst)) { + /* zero copy is possible by just swapping buffers */ + struct buffer tmp = *dst; + *dst = *src; + *src = tmp; + goto leave; + } block1 = b_contig_data(src, 0); if (block1 > ret)