aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2022-03-07 00:36:16 +0200
committerLasse Collin <lasse.collin@tukaani.org>2022-03-07 00:36:16 +0200
commit6c6da57ae2aa962aabde6892442227063d87e88c (patch)
treeb84567e4cd0fd109bce7de30e49caba11d9e828b
parentliblzma: Add threaded .xz decompressor. (diff)
downloadxz-6c6da57ae2aa962aabde6892442227063d87e88c.tar.xz
xz: Add initial support for threaded decompression.
If threading support is enabled at build time, this will use lzma_stream_decoder_mt() even for single-threaded mode. With memlimit_threading=0 the behavior should be identical. This needs some work like adding --memlimit-threading=LIMIT. The original patch from Sebastian Andrzej Siewior included a method to get currently available RAM on Linux. It might be one way to go but as it is Linux-only, the available-RAM approach needs work for portability or using a fallback method on other OSes. The man page wasn't updated yet.
-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: