> To be backward compatible, maybe it needs extra syntax within the
> --threads option or a new command line option. Both are a bit annoying
> and ugly but I don't have a better idea.

I added a flag to the threading option to force multithreading or
single threading modes. Right now, if the user specifies -T s4, xz
will ignore the 4 threads requested and do single threaded mode.
Should I issue a warning message, cause an error, or is this the
preferred behavior?

> common.h is internal to liblzma and must not be used from xz. Maybe
> LZMA_THREADS_MAX could be moved to the public API, I don't know right
> now.

I put the hardcoded value back.

---
src/xz/args.c | 38 +++++++++++++++++++++++++++++++++++---
src/xz/coder.c | 16 +++++++++++++---
src/xz/coder.h | 3 +++
src/xz/message.c | 7 +++++--
4 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/xz/args.c b/src/xz/args.c
index 9238fb3..2fe98cd 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -115,6 +115,40 @@ parse_block_list(char *str)
return;
}
+static void
+parse_threading(char* optarg){
+ char multithreaded_mode = optarg[0];
+ bool threading_specified = false;
+
+ if(multithreaded_mode == 'm' || multithreaded_mode == 's'){
+ threading_specified = true;
+ optarg++;
+ }
+
+ // The max is from src/liblzma/common/common.h.
+ uint64_t threads_requested = str_to_uint64("threads",
+ optarg, 0, 16384);
+ hardware_threads_set(threads_requested);
+
+ if(threading_specified){
+ if(multithreaded_mode == 'm'){
+ set_multithreaded_mode(true);
+ }
+ else if(multithreaded_mode == 's') {
+ set_multithreaded_mode(false);
+ }
+ }
+ else {
+ //Default for --threads=1 is single threaded mode
+ if(threads_requested == 1){
+ set_multithreaded_mode(false);
+ }
+ //Default for --threads=0 or --threads=[n>1] is multi threaded mode
+ else {
+ set_multithreaded_mode(true);
+ }
+ }
+}
static void
parse_real(args_info *args, int argc, char **argv)
@@ -247,9 +281,7 @@ parse_real(args_info *args, int argc, char **argv)
break;
case 'T':
- // The max is from src/liblzma/common/common.h.
- hardware_threads_set(str_to_uint64("threads",
- optarg, 0, 16384));
+ parse_threading(optarg);
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);
diff --git a/src/xz/message.c b/src/xz/message.c
index 00eb65b..ceb1cdd 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -1159,8 +1159,11 @@ message_help(bool long_help)
" does not affect decompressor memory requirements"));
puts(_(
-" -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
-" to use as many threads as there are processor cores"));
+" -T[m|s],\n"
+" --threads[m|s]=NUM use at most NUM threads; the default is 1; set to 0\n"
+" to use as many threads as there are processor cores\n"
+" if s is set, force single threaded mode; if m i set,\n"
+" force multithreaded mode"));
if (long_help) {
puts(_(
-- 
2.25.1
From f855507add2f7d2e1822584f76c7ad56fe7d249d Mon Sep 17 00:00:00 2001
From: jiat75 <jiat0...@gmail.com>
Date: Tue, 30 Nov 2021 22:07:46 +0800
Subject: [PATCH] Multithreaded mode now always uses stream_encoder_mt

---
 src/xz/args.c    | 38 +++++++++++++++++++++++++++++++++++---
 src/xz/coder.c   | 16 +++++++++++++---
 src/xz/coder.h   |  3 +++
 src/xz/message.c |  7 +++++--
 4 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/xz/args.c b/src/xz/args.c
index 9238fb3..2fe98cd 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -115,6 +115,40 @@ parse_block_list(char *str)
 	return;
 }
 
+static void
+parse_threading(char* optarg){
+	char multithreaded_mode = optarg[0];
+	bool threading_specified = false;
+
+	if(multithreaded_mode == 'm' || multithreaded_mode == 's'){
+		threading_specified = true;
+		optarg++;
+	}
+	
+	// The max is from src/liblzma/common/common.h.
+	uint64_t threads_requested = str_to_uint64("threads",
+			optarg, 0, 16384);
+	hardware_threads_set(threads_requested);
+	
+	if(threading_specified){
+		if(multithreaded_mode == 'm'){
+			set_multithreaded_mode(true);
+		}
+		else if(multithreaded_mode == 's') {
+			set_multithreaded_mode(false);
+		}
+	}
+	else {
+		//Default for --threads=1 is single threaded mode
+		if(threads_requested == 1){
+			set_multithreaded_mode(false);
+		}
+		//Default for --threads=0 or --threads=[n>1] is multi threaded mode
+		else {
+			set_multithreaded_mode(true);
+		}
+	}
+}
 
 static void
 parse_real(args_info *args, int argc, char **argv)
@@ -247,9 +281,7 @@ parse_real(args_info *args, int argc, char **argv)
 			break;
 
 		case 'T':
-			// The max is from src/liblzma/common/common.h.
-			hardware_threads_set(str_to_uint64("threads",
-					optarg, 0, 16384));
+			parse_threading(optarg);
 			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);
diff --git a/src/xz/message.c b/src/xz/message.c
index 00eb65b..ceb1cdd 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -1159,8 +1159,11 @@ message_help(bool long_help)
 "                      does not affect decompressor memory requirements"));
 
 	puts(_(
-"  -T, --threads=NUM   use at most NUM threads; the default is 1; set to 0\n"
-"                      to use as many threads as there are processor cores"));
+"  -T[m|s],\n"
+"  --threads[m|s]=NUM  use at most NUM threads; the default is 1; set to 0\n"                    
+"                      to use as many threads as there are processor cores\n"
+"                      if s is set, force single threaded mode; if m i set,\n"
+"                      force multithreaded mode"));
 
 	if (long_help) {
 		puts(_(
-- 
2.25.1

Reply via email to