aboutsummaryrefslogtreecommitdiff
path: root/src/xz/coder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xz/coder.c')
-rw-r--r--src/xz/coder.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/xz/coder.c b/src/xz/coder.c
index 85f95439..dc70f1cc 100644
--- a/src/xz/coder.c
+++ b/src/xz/coder.c
@@ -51,7 +51,7 @@ static lzma_check check;
/// This becomes false if the --check=CHECK option is used.
static bool check_default = true;
-#if defined(HAVE_ENCODERS) && defined(MYTHREAD_ENABLED)
+#ifdef MYTHREAD_ENABLED
static lzma_mt mt_options = {
.flags = 0,
.timeout = 300,
@@ -520,9 +520,43 @@ coder_init(file_pair *pair)
break;
case FORMAT_XZ:
+# ifdef MYTHREAD_ENABLED
+ mt_options.flags = flags;
+
+ mt_options.threads = hardware_threads_get();
+
+ // TODO: Support --memlimit-threading=LIMIT.
+ mt_options.memlimit_stop
+ = hardware_memlimit_get(MODE_DECOMPRESS);
+ mt_options.memlimit_threading
+ = mt_options.memlimit_stop;
+
+ if (mt_options.threads == 1) {
+ // Single-threaded mode was requested. Force
+ // the decoder to use minimal memory, matching
+ // the behavior of lzma_stream_decoder().
+ mt_options.memlimit_threading = 0;
+
+ } else if (mt_options.memlimit_threading
+ == UINT64_MAX) {
+ // TODO: Support --memlimit-threading=LIMIT.
+ //
+ // If lzma_physmem() fails, it returns 0 and
+ // we end up with a single thread.
+ //
+ // NOTE: It is assential that we never end up
+ // with an effectively infinite value in
+ // memlimit_threading!
+ mt_options.memlimit_threading
+ = lzma_physmem() / 4;
+ }
+
+ ret = lzma_stream_decoder_mt(&strm, &mt_options);
+# else
ret = lzma_stream_decoder(&strm,
hardware_memlimit_get(
MODE_DECOMPRESS), flags);
+# endif
break;
case FORMAT_LZMA: