From f21ebeece53687b17d64fa444ceb3648439f5a8a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 31 Jan 2018 17:19:59 +0100 Subject: [PATCH] gzip: flush output buffer after stored blocks, they are not 32-bit aligned function old new delta flush_block 665 671 +6 Signed-off-by: Denys Vlasenko --- archival/gzip.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/archival/gzip.c b/archival/gzip.c index 6083cde88..7df38c2bc 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -486,19 +486,26 @@ static void put_16bit(ush w) #define OPTIMIZED_PUT_32BIT (CONFIG_GZIP_FAST > 0 && BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN) static void put_32bit(ulg n) { -#if OPTIMIZED_PUT_32BIT - unsigned outcnt = G1.outcnt; - if (outcnt < OUTBUFSIZ-4) { - /* Common case */ - ulg *dst32 = (void*) &G1.outbuf[outcnt]; - *dst32 = n; /* unaligned LSB 32-bit store */ - G1.outcnt = outcnt + 4; - return; + if (OPTIMIZED_PUT_32BIT) { + unsigned outcnt = G1.outcnt; + if (outcnt < OUTBUFSIZ-4) { + /* Common case */ + ulg *dst32 = (void*) &G1.outbuf[outcnt]; + *dst32 = n; /* unaligned LSB 32-bit store */ + //bb_error_msg("%p", dst32); // store alignment debugging + G1.outcnt = outcnt + 4; + return; + } } -#endif put_16bit(n); put_16bit(n >> 16); } +static ALWAYS_INLINE void flush_outbuf_if_32bit_optimized(void) +{ + /* If put_32bit() performs 32bit stores && it is used in send_bits() */ + if (OPTIMIZED_PUT_32BIT && BUF_SIZE > 16) + flush_outbuf(); +} /* =========================================================================== * Run a set of bytes through the crc shift register. If s is a NULL @@ -626,6 +633,8 @@ static void copy_block(char *buf, unsigned len, int header) while (len--) { put_8bit(*buf++); } + /* The above can 32-bit misalign outbuf */ + flush_outbuf_if_32bit_optimized(); } @@ -2110,12 +2119,8 @@ static void zip(void) put_16bit(deflate_flags | 0x300); /* extra flags. OS id = 3 (Unix) */ -#if OPTIMIZED_PUT_32BIT - /* put_32bit() performs 32bit stores. If we use it in send_bits()... */ - if (BUF_SIZE > 16) - /* then all stores are misaligned, unless we flush the buffer now */ - flush_outbuf(); -#endif + /* The above 32-bit misaligns outbuf (10 bytes are stored), flush it */ + flush_outbuf_if_32bit_optimized(); deflate();