diff --git a/contrib/liblzma/compress_easy_mt.cpp b/contrib/liblzma/compress_easy_mt.cpp index 2ba1da2..9c3612a 100644 --- a/contrib/liblzma/compress_easy_mt.cpp +++ b/contrib/liblzma/compress_easy_mt.cpp @@ -78,7 +78,7 @@ bool init_decoder(lzma_stream *strm) return check(ret); } -bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t &memory_usage) +bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage) { // The threaded encoder takes the options as pointer to // a lzma_mt structure. @@ -88,7 +88,7 @@ bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t &memory_usage) mt .flags = 0; // Let liblzma determine a sane block size. - mt .block_size = 16 * 1024 * 1024; + mt .block_size = 0; // Use no timeout for lzma_code() calls by setting timeout // to zero. That is, sometimes lzma_code() might block for @@ -109,6 +109,20 @@ bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t &memory_usage) mt.threads = threads; + uint64_t preset_memory_usage; + int preset_to_use = 0; + for (int preset = 1; preset <= 9; preset++) { + mt.preset = preset; + preset_memory_usage = lzma_stream_encoder_mt_memusage(&mt); + if (preset_memory_usage > max_memory) break; + memory_usage = preset_memory_usage; + preset_to_use = preset; + } + + if (preset_to_use == 0) return false; + + mt.preset = preset_to_use; + // Initialize the threaded encoder. lzma_ret ret = lzma_stream_encoder_mt(strm, &mt); diff --git a/contrib/liblzma/precomp_xz.h b/contrib/liblzma/precomp_xz.h index 029e897..201d5e3 100644 --- a/contrib/liblzma/precomp_xz.h +++ b/contrib/liblzma/precomp_xz.h @@ -5,7 +5,8 @@ bool init_lzma1(lzma_stream *strm); bool init_lzma2(lzma_stream *strm); -bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t &memory_usage); +bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage); + bool init_decoder(lzma_stream *strm); #endif /* ifndef PRECOMP_XZ_H */ diff --git a/precomp.cpp b/precomp.cpp index 707c250..fb57311 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -9190,9 +9190,16 @@ void init_compress_otf() { } case OTF_XZ_MT: { uint64_t memory_usage = 0; + // As default, use 2 GB memory for LZMA, only 1 GB in the 32-bit windows variant + uint64_t max_memory = 2 * 1024 * 1024 * 1024LL; + #ifndef UNIX + #ifndef BIT64 + max_memory = 1 * 1024 * 1024 * 1024LL; + #endif + #endif int threads = std::thread::hardware_concurrency(); if (threads == 0) threads = 2; - if (!init_encoder_mt(&otf_xz_stream_c, threads, memory_usage)) { + if (!init_encoder_mt(&otf_xz_stream_c, threads, max_memory, memory_usage)) { printf("ERROR: xz Multi-Threaded init failed\n"); exit(1); }