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