This patch addresses the issues with reproducible builds when using multithreaded xz. Previously, specifying --threads=1 instead of --threads=[n>1] creates different output. Now, setting any number of threads forces multithreading mode, even if there is only 1 worker thread.
--- src/xz/Makefile.am | 1 + src/xz/args.c | 4 +++- src/xz/coder.c | 16 +++++++++++++--- src/xz/coder.h | 3 +++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/xz/Makefile.am b/src/xz/Makefile.am index 4bc64f3..07ae9eb 100644 --- a/src/xz/Makefile.am +++ b/src/xz/Makefile.am @@ -51,6 +51,7 @@ xz_CPPFLAGS = \ -DLOCALEDIR=\"$(localedir)\" \ -I$(top_srcdir)/src/common \ -I$(top_srcdir)/src/liblzma/api \ + -I$(top_srcdir)/src/liblzma/common \ -I$(top_builddir)/lib xz_LDADD = $(top_builddir)/src/liblzma/liblzma.la $(CAPSICUM_LIB) diff --git a/src/xz/args.c b/src/xz/args.c index 9238fb3..c09c6b6 100644 --- a/src/xz/args.c +++ b/src/xz/args.c @@ -13,6 +13,7 @@ /////////////////////////////////////////////////////////////////////////////// #include "private.h" +#include "common.h" #include "getopt.h" #include <ctype.h> @@ -249,7 +250,8 @@ parse_real(args_info *args, int argc, char **argv) case 'T': // The max is from src/liblzma/common/common.h. hardware_threads_set(str_to_uint64("threads", - optarg, 0, 16384)); + optarg, 0, LZMA_THREADS_MAX)); + set_multithreaded_mode(true); break; // --version diff --git a/src/xz/coder.c b/src/xz/coder.c index 85f9543..8dfdeb2 100644 --- a/src/xz/coder.c +++ b/src/xz/coder.c @@ -51,6 +51,9 @@ static lzma_check check; /// This becomes false if the --check=CHECK option is used. static bool check_default = true; +/// Flag to indicate multithreaded compression +static bool multithreaded_mode = false; + #if defined(HAVE_ENCODERS) && defined(MYTHREAD_ENABLED) static lzma_mt mt_options = { .flags = 0, @@ -211,10 +214,11 @@ coder_set_compression_settings(void) } } - if (hardware_threads_get() > 1) { + if (multithreaded_mode) { message(V_WARNING, _("Switching to single-threaded " "mode due to --flush-timeout")); hardware_threads_set(1); + set_multithreaded_mode(false); } } @@ -225,7 +229,7 @@ coder_set_compression_settings(void) if (opt_mode == MODE_COMPRESS) { #ifdef HAVE_ENCODERS # ifdef MYTHREAD_ENABLED - if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) { + if (opt_format == FORMAT_XZ && (hardware_threads_get() > 1 || multithreaded_mode)) { mt_options.threads = hardware_threads_get(); mt_options.block_size = opt_block_size; mt_options.check = check; @@ -446,7 +450,7 @@ coder_init(file_pair *pair) case FORMAT_XZ: # ifdef MYTHREAD_ENABLED - if (hardware_threads_get() > 1) + if (multithreaded_mode) ret = lzma_stream_encoder_mt( &strm, &mt_options); else @@ -933,6 +937,12 @@ coder_run(const char *filename) return; } +extern void +set_multithreaded_mode(bool mode) +{ + multithreaded_mode = mode; +} + #ifndef NDEBUG extern void diff --git a/src/xz/coder.h b/src/xz/coder.h index 583da8f..178f036 100644 --- a/src/xz/coder.h +++ b/src/xz/coder.h @@ -70,6 +70,9 @@ extern void coder_set_compression_settings(void); /// Compress or decompress the given file extern void coder_run(const char *filename); +//// Set multithread mode true/false +extern void set_multithreaded_mode(bool mode); + #ifndef NDEBUG /// Free the memory allocated for the coder and kill the worker threads. extern void coder_free(void); -- 2.25.1