From 772ddd6500a74220e641782cc2ee892433197192 Mon Sep 17 00:00:00 2001 From: IBM developers Date: Mon, 25 May 2020 14:09:48 +0200 Subject: [PATCH] Fix for Z hardware-accelerated deflate for s390x architectures --- configure | 7 +++ contrib/s390/dfltcc.c | 94 ++++++++++++++++++++--------------- contrib/s390/dfltcc_deflate.h | 10 ++-- deflate.c | 12 +++-- 4 files changed, 76 insertions(+), 47 deletions(-) diff --git a/configure b/configure index 66caece..bfe4386 100755 --- a/configure +++ b/configure @@ -114,6 +114,7 @@ case "$1" in echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + echo ' [--dfltcc]' | tee -a configure.log exit 0 ;; -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; @@ -137,6 +138,12 @@ case "$1" in -c* | --const) zconst=1; shift ;; -w* | --warn) warn=1; shift ;; -d* | --debug) debug=1; shift ;; + --dfltcc) + CFLAGS="$CFLAGS -DDFLTCC" + OBJC="$OBJC dfltcc.o" + PIC_OBJC="$PIC_OBJC dfltcc.lo" + shift + ;; *) echo "unknown option: $1" | tee -a configure.log echo "$0 --help for help" | tee -a configure.log diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c index d187796..face8f1 100644 --- a/contrib/s390/dfltcc.c +++ b/contrib/s390/dfltcc.c @@ -2,8 +2,8 @@ /* Use the following commands to build zlib with DFLTCC support: - $ CFLAGS=-DDFLTCC ./configure - $ make OBJA=dfltcc.o PIC_OBJA=dfltcc.lo + $ ./configure --dfltcc + $ make */ #define _GNU_SOURCE @@ -230,31 +230,28 @@ struct dfltcc_state { /* Compress. */ -local inline int dfltcc_are_params_ok(int level, - uInt window_bits, - int strategy, - uLong level_mask); -local inline int dfltcc_are_params_ok(level, window_bits, strategy, level_mask) +local inline int dfltcc_can_deflate_with_params(z_streamp strm, + int level, + uInt window_bits, + int strategy); +local inline int dfltcc_can_deflate_with_params(strm, + level, + window_bits, + strategy) + z_streamp strm; int level; uInt window_bits; int strategy; - uLong level_mask; -{ - return (level_mask & (1 << level)) != 0 && - (window_bits == HB_BITS) && - (strategy == Z_FIXED || strategy == Z_DEFAULT_STRATEGY); -} - - -int ZLIB_INTERNAL dfltcc_can_deflate(strm) - z_streamp strm; { deflate_state FAR *state = (deflate_state FAR *)strm->state; struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); /* Unsupported compression settings */ - if (!dfltcc_are_params_ok(state->level, state->w_bits, state->strategy, - dfltcc_state->level_mask)) + if ((dfltcc_state->level_mask & (1 << level)) == 0) + return 0; + if (window_bits != HB_BITS) + return 0; + if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) return 0; /* Unsupported hardware */ @@ -266,6 +263,17 @@ int ZLIB_INTERNAL dfltcc_can_deflate(strm) return 1; } +int ZLIB_INTERNAL dfltcc_can_deflate(strm) + z_streamp strm; +{ + deflate_state FAR *state = (deflate_state FAR *)strm->state; + + return dfltcc_can_deflate_with_params(strm, + state->level, + state->w_bits, + state->strategy); +} + local void dfltcc_gdht OF((z_streamp strm)); local void dfltcc_gdht(strm) z_streamp strm; @@ -349,22 +357,24 @@ again: soft_bcc = 0; no_flush = flush == Z_NO_FLUSH; - /* Trailing empty block. Switch to software, except when Continuation Flag - * is set, which means that DFLTCC has buffered some output in the - * parameter block and needs to be called again in order to flush it. + /* No input data. Return, except when Continuation Flag is set, which means + * that DFLTCC has buffered some output in the parameter block and needs to + * be called again in order to flush it. */ - if (flush == Z_FINISH && strm->avail_in == 0 && !param->cf) { - if (param->bcf) { - /* A block is still open, and the hardware does not support closing - * blocks without adding data. Thus, close it manually. - */ + if (strm->avail_in == 0 && !param->cf) { + /* A block is still open, and the hardware does not support closing + * blocks without adding data. Thus, close it manually. + */ + if (!no_flush && param->bcf) { send_eobs(strm, param); param->bcf = 0; } - return 0; - } - - if (strm->avail_in == 0 && !param->cf) { + /* Let one of deflate_* functions write a trailing empty block. */ + if (flush == Z_FINISH) + return 0; + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; *result = need_more; return 1; } @@ -418,7 +428,7 @@ again: param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; if (!no_flush) /* We need to close a block. Always do this in software - when there is - * no input data, the hardware will not nohor BCC. */ + * no input data, the hardware will not honor BCC. */ soft_bcc = 1; if (flush == Z_FINISH && !param->bcf) /* We are about to open a BFINAL block, set Block Header Final bit @@ -433,8 +443,8 @@ again: param->sbb = (unsigned int)state->bi_valid; if (param->sbb > 0) *strm->next_out = (Bytef)state->bi_buf; - if (param->hl) - param->nt = 0; /* Honor history */ + /* Honor history and check value */ + param->nt = 0; param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler; /* When opening a block, choose a Huffman-Table Type */ @@ -792,17 +802,20 @@ void ZLIB_INTERNAL dfltcc_free_window(strm, w) fly with deflateParams, we need to convert between hardware and software window formats. */ -int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy) +int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush) z_streamp strm; int level; int strategy; + int *flush; { deflate_state FAR *state = (deflate_state FAR *)strm->state; struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state); struct dfltcc_param_v0 FAR *param = &dfltcc_state->param; int could_deflate = dfltcc_can_deflate(strm); - int can_deflate = dfltcc_are_params_ok(level, state->w_bits, strategy, - dfltcc_state->level_mask); + int can_deflate = dfltcc_can_deflate_with_params(strm, + level, + state->w_bits, + strategy); if (can_deflate == could_deflate) /* We continue to work in the same mode - no changes needed */ @@ -812,8 +825,11 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy) /* DFLTCC was not used yet - no changes needed */ return Z_OK; - /* Switching between hardware and software is not implemented */ - return Z_STREAM_ERROR; + /* For now, do not convert between window formats - simply get rid of the + * old data instead. + */ + *flush = Z_FULL_FLUSH; + return Z_OK; } /* diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h index a129a91..947b1e4 100644 --- a/contrib/s390/dfltcc_deflate.h +++ b/contrib/s390/dfltcc_deflate.h @@ -9,7 +9,8 @@ int ZLIB_INTERNAL dfltcc_deflate OF((z_streamp strm, block_state *result)); int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm, int level, - int strategy)); + int strategy, + int *flush)); int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm, const Bytef *dictionary, uInt dict_length)); @@ -29,11 +30,14 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm, } while (0) #define DEFLATE_RESET_KEEP_HOOK(strm) \ dfltcc_reset((strm), sizeof(deflate_state)) -#define DEFLATE_PARAMS_HOOK(strm, level, strategy) \ +#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ do { \ int err; \ \ - err = dfltcc_deflate_params((strm), (level), (strategy)); \ + err = dfltcc_deflate_params((strm), \ + (level), \ + (strategy), \ + (hook_flush)); \ if (err == Z_STREAM_ERROR) \ return err; \ } while (0) diff --git a/deflate.c b/deflate.c index 9b09718..9284483 100644 --- a/deflate.c +++ b/deflate.c @@ -74,7 +74,7 @@ const char deflate_copyright[] = #define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) #define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) #define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) -#define DEFLATE_PARAMS_HOOK(strm, level, strategy) do {} while (0) +#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 #define DEFLATE_HOOK(strm, flush, bstate) 0 @@ -589,6 +589,7 @@ int ZEXPORT deflateParams(strm, level, strategy) { deflate_state *s; compress_func func; + int hook_flush = Z_NO_FLUSH; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; @@ -601,13 +602,14 @@ int ZEXPORT deflateParams(strm, level, strategy) if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } - DEFLATE_PARAMS_HOOK(strm, level, strategy); + DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); func = configuration_table[s->level].func; - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->high_water) { + if ((strategy != s->strategy || func != configuration_table[level].func || + hook_flush != Z_NO_FLUSH) && s->last_flush != -2) { /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); + int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ? + hook_flush : Z_BLOCK); if (err == Z_STREAM_ERROR) return err; if (strm->avail_out == 0) -- 2.24.1