summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2018-01-31 17:19:59 +0100
committerDenys Vlasenko2018-01-31 17:19:59 +0100
commitf21ebeece53687b17d64fa444ceb3648439f5a8a (patch)
treebcc41395fbe386a8ed0c8a88983974ae40f10068
parentba63d70e2d3a24670813dc33fca4450a25b281b6 (diff)
downloadbusybox-f21ebeece53687b17d64fa444ceb3648439f5a8a.zip
busybox-f21ebeece53687b17d64fa444ceb3648439f5a8a.tar.gz
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 <vda.linux@googlemail.com>
-rw-r--r--archival/gzip.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/archival/gzip.c b/archival/gzip.c
index 6083cde..7df38c2 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();