From: Rui Paulo Date: Tue, 17 Feb 2015 19:19:55 +0000 (-0800) Subject: xz: add the xz:threads option. X-Git-Tag: v3.1.900a~121^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F107%2Fhead;p=thirdparty%2Flibarchive.git xz: add the xz:threads option. It's now possible to chose the number of threads used by the lzma multi-threaded compressor using tar ... --xz --option xz:threads=N where N is the number of threads. When N is 0, it will create threads based on the number of CPUs (following the xz(1) model). --- diff --git a/libarchive/archive_write_add_filter_xz.c b/libarchive/archive_write_add_filter_xz.c index b6c76c6e3..88a427dca 100644 --- a/libarchive/archive_write_add_filter_xz.c +++ b/libarchive/archive_write_add_filter_xz.c @@ -100,6 +100,7 @@ archive_write_add_filter_lzip(struct archive *a) struct private_data { int compression_level; + uint32_t threads; lzma_stream stream; lzma_filter lzmafilters[2]; lzma_options_lzma lzma_opt; @@ -151,6 +152,7 @@ common_setup(struct archive_write_filter *f) } f->data = data; data->compression_level = LZMA_PRESET_DEFAULT; + data->threads = 1; f->open = &archive_compressor_xz_open; f->close = archive_compressor_xz_close; f->free = archive_compressor_xz_free; @@ -230,9 +232,9 @@ archive_compressor_xz_init_stream(struct archive_write_filter *f, data->stream.avail_out = data->compressed_buffer_size; if (f->code == ARCHIVE_FILTER_XZ) { #ifdef HAVE_LZMA_STREAM_ENCODER_MT - if (lzma_cputhreads() > 1) { + if (data->threads != 1) { bzero(&mt_options, sizeof(mt_options)); - mt_options.threads = lzma_cputhreads(); + mt_options.threads = data->threads; mt_options.timeout = 300; mt_options.filters = data->lzmafilters; mt_options.check = LZMA_CHECK_CRC64; @@ -387,6 +389,17 @@ archive_compressor_xz_options(struct archive_write_filter *f, if (data->compression_level > 6) data->compression_level = 6; return (ARCHIVE_OK); + } else if (strcmp(key, "threads") == 0) { + if (value == NULL) + return (ARCHIVE_WARN); + data->threads = (int)strtoul(value, NULL, 10); + if (data->threads == 0 && errno != 0) { + data->threads = 1; + return (ARCHIVE_WARN); + } + if (data->threads == 0) + data->threads = lzma_cputhreads(); + return (ARCHIVE_OK); } /* Note: The "warn" return is just to inform the options diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c index c3fe7c1cd..1d06bb897 100644 --- a/libarchive/archive_write_set_format_xar.c +++ b/libarchive/archive_write_set_format_xar.c @@ -242,6 +242,7 @@ struct xar { enum sumalg opt_sumalg; enum enctype opt_compression; int opt_compression_level; + uint32_t opt_threads; struct chksumwork a_sumwrk; /* archived checksum. */ struct chksumwork e_sumwrk; /* extracted checksum. */ @@ -317,7 +318,7 @@ static int compression_end_bzip2(struct archive *, struct la_zstream *); static int compression_init_encoder_lzma(struct archive *, struct la_zstream *, int); static int compression_init_encoder_xz(struct archive *, - struct la_zstream *, int); + struct la_zstream *, int, int); #if defined(HAVE_LZMA_H) static int compression_code_lzma(struct archive *, struct la_zstream *, enum la_zaction); @@ -380,9 +381,10 @@ archive_write_set_format_xar(struct archive *_a) /* Set default checksum type. */ xar->opt_toc_sumalg = CKSUM_SHA1; xar->opt_sumalg = CKSUM_SHA1; - /* Set default compression type and level. */ + /* Set default compression type, level, and number of threads. */ xar->opt_compression = GZIP; xar->opt_compression_level = 6; + xar->opt_threads = 1; a->format_data = xar; @@ -493,6 +495,21 @@ xar_options(struct archive_write *a, const char *key, const char *value) } return (ARCHIVE_OK); } + if (strcmp(key, "threads") == 0) { + if (value == NULL) + return (ARCHIVE_FAILED); + xar->opt_threads = (int)strtoul(value, NULL, 10); + if (xar->opt_threads == 0 && errno != 0) { + xar->opt_threads = 1; + archive_set_error(&(a->archive), + ARCHIVE_ERRNO_MISC, + "Illegal value `%s'", + value); + return (ARCHIVE_FAILED); + } + if (xar->opt_threads == 0) + xar->opt_threads = lzma_cputhreads(); + } /* Note: The "warn" return is just to inform the options * supervisor that we didn't handle it. It will generate @@ -2848,7 +2865,7 @@ compression_init_encoder_lzma(struct archive *a, static int compression_init_encoder_xz(struct archive *a, - struct la_zstream *lastrm, int level) + struct la_zstream *lastrm, int level, int threads) { static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; lzma_stream *strm; @@ -2883,9 +2900,9 @@ compression_init_encoder_xz(struct archive *a, *strm = lzma_init_data; #ifdef HAVE_LZMA_STREAM_ENCODER_MT - if (lzma_cputhreads() > 1) { + if (threads > 1) { bzero(&mt_options, sizeof(mt_options)); - mt_options.threads = lzma_cputhreads(); + mt_options.threads = threads; mt_options.timeout = 300; mt_options.filters = lzmafilters; mt_options.check = LZMA_CHECK_CRC64; @@ -2992,10 +3009,11 @@ compression_init_encoder_lzma(struct archive *a, } static int compression_init_encoder_xz(struct archive *a, - struct la_zstream *lastrm, int level) + struct la_zstream *lastrm, int level, int threads) { (void) level; /* UNUSED */ + (void) threads; /* UNUSED */ if (lastrm->valid) compression_end(a, lastrm); return (compression_unsupported_encoder(a, lastrm, "xz")); @@ -3028,7 +3046,7 @@ xar_compression_init_encoder(struct archive_write *a) case XZ: r = compression_init_encoder_xz( &(a->archive), &(xar->stream), - xar->opt_compression_level); + xar->opt_compression_level, xar->opt_threads); break; default: r = ARCHIVE_OK;