summaryrefslogtreecommitdiff
path: root/src/liblzma/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/liblzma/common')
-rw-r--r--src/liblzma/common/alone_decoder.c6
-rw-r--r--src/liblzma/common/filter_common.c4
-rw-r--r--src/liblzma/common/lzip_decoder.c3
-rw-r--r--src/liblzma/common/outqueue.h1
-rw-r--r--src/liblzma/common/stream_decoder_mt.c79
-rw-r--r--src/liblzma/common/vli_decoder.c2
6 files changed, 44 insertions, 51 deletions
diff --git a/src/liblzma/common/alone_decoder.c b/src/liblzma/common/alone_decoder.c
index e2b58e1f3758..8ebbbe8aa70f 100644
--- a/src/liblzma/common/alone_decoder.c
+++ b/src/liblzma/common/alone_decoder.c
@@ -128,8 +128,10 @@ alone_decode(void *coder_ptr, const lzma_allocator *allocator,
lzma_set_ext_size(coder->options, coder->uncompressed_size);
// Calculate the memory usage so that it is ready
- // for SEQ_CODER_INIT.
- coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ // for SEQ_CODER_INIT. We know that lc/lp/pb are valid
+ // so we can use the _nocheck variant.
+ coder->memusage
+ = lzma_lzma_decoder_memusage_nocheck(&coder->options)
+ LZMA_MEMUSAGE_BASE;
coder->pos = 0;
diff --git a/src/liblzma/common/filter_common.c b/src/liblzma/common/filter_common.c
index d15d9cc94f99..6c06c78ddc15 100644
--- a/src/liblzma/common/filter_common.c
+++ b/src/liblzma/common/filter_common.c
@@ -213,8 +213,8 @@ lzma_filters_copy(const lzma_filter *src, lzma_filter *real_dest,
error:
// Free the options which we have already allocated.
- while (i-- > 0)
- lzma_free(dest[i].options, allocator);
+ while (i > 0)
+ lzma_free(dest[--i].options, allocator);
return ret;
}
diff --git a/src/liblzma/common/lzip_decoder.c b/src/liblzma/common/lzip_decoder.c
index 4dff2d5889ea..5630039f97b9 100644
--- a/src/liblzma/common/lzip_decoder.c
+++ b/src/liblzma/common/lzip_decoder.c
@@ -212,7 +212,8 @@ lzip_decode(void *coder_ptr, const lzma_allocator *allocator,
coder->options.pb = LZIP_PB;
// Calculate the memory usage.
- coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
+ coder->memusage
+ = lzma_lzma_decoder_memusage_nocheck(&coder->options)
+ LZMA_MEMUSAGE_BASE;
// Initialization is a separate step because if we return
diff --git a/src/liblzma/common/outqueue.h b/src/liblzma/common/outqueue.h
index 25f071977a8f..0e4e9141dab5 100644
--- a/src/liblzma/common/outqueue.h
+++ b/src/liblzma/common/outqueue.h
@@ -188,6 +188,7 @@ extern bool lzma_outq_is_readable(const lzma_outq *outq);
/// \brief Read finished data
///
/// \param outq Pointer to an output queue
+/// \param allocator lzma_allocator for custom allocator functions
/// \param out Beginning of the output buffer
/// \param out_pos The next byte will be written to
/// out[*out_pos].
diff --git a/src/liblzma/common/stream_decoder_mt.c b/src/liblzma/common/stream_decoder_mt.c
index 271f9b07c4b8..d51366e1b02c 100644
--- a/src/liblzma/common/stream_decoder_mt.c
+++ b/src/liblzma/common/stream_decoder_mt.c
@@ -33,26 +33,6 @@ typedef enum {
} worker_state;
-typedef enum {
- /// Partial updates (storing of worker thread progress
- /// to lzma_outbuf) are disabled.
- PARTIAL_DISABLED,
-
- /// Main thread requests partial updates to be enabled but
- /// no partial update has been done by the worker thread yet.
- ///
- /// Changing from PARTIAL_DISABLED to PARTIAL_START requires
- /// use of the worker-thread mutex. Other transitions don't
- /// need a mutex.
- PARTIAL_START,
-
- /// Partial updates are enabled and the worker thread has done
- /// at least one partial update.
- PARTIAL_ENABLED,
-
-} partial_update_mode;
-
-
struct worker_thread {
/// Worker state is protected with our mutex.
worker_state state;
@@ -104,10 +84,18 @@ struct worker_thread {
/// happen if all worker threads were frequently locking the main
/// mutex to update their outbuf->pos.
///
- /// Only when partial_update is something else than PARTIAL_DISABLED,
- /// this worker thread will update outbuf->pos after each call to
- /// the Block decoder.
- partial_update_mode partial_update;
+ /// When partial_update_enabled is true, this worker thread will
+ /// update outbuf->pos and outbuf->decoder_in_pos after each call
+ /// to the Block decoder. This is initially false. Main thread may
+ /// set this to true.
+ bool partial_update_enabled;
+
+ /// Once the main thread has set partial_updated_enabled = true,
+ /// we will do the first partial update as soon as we can and
+ /// set partial_update_started = true. After the first update,
+ /// we only update if we have made progress. This avoids useless
+ /// locking of thr->coder->mutex.
+ bool partial_update_started;
/// Block decoder
lzma_next_coder block_decoder;
@@ -335,7 +323,7 @@ worker_enable_partial_update(void *thr_ptr)
struct worker_thread *thr = thr_ptr;
mythread_sync(thr->mutex) {
- thr->partial_update = PARTIAL_START;
+ thr->partial_update_enabled = true;
mythread_cond_signal(&thr->cond);
}
}
@@ -346,7 +334,7 @@ worker_decoder(void *thr_ptr)
{
struct worker_thread *thr = thr_ptr;
size_t in_filled;
- partial_update_mode partial_update;
+ bool partial_update_enabled;
lzma_ret ret;
next_loop_lock:
@@ -378,14 +366,16 @@ next_loop_unlocked:
thr->progress_out = thr->out_pos;
// If we don't have any new input, wait for a signal from the main
- // thread except if partial output has just been enabled. In that
+ // thread except if partial output has just been enabled
+ // (partial_update_enabled is true but _started is false). In that
// case we will do one normal run so that the partial output info
// gets passed to the main thread. The call to block_decoder.code()
// is useless but harmless as it can occur only once per Block.
in_filled = thr->in_filled;
- partial_update = thr->partial_update;
+ partial_update_enabled = thr->partial_update_enabled;
- if (in_filled == thr->in_pos && partial_update != PARTIAL_START) {
+ if (in_filled == thr->in_pos && !(partial_update_enabled
+ && !thr->partial_update_started)) {
mythread_cond_wait(&thr->cond, &thr->mutex);
goto next_loop_unlocked;
}
@@ -407,23 +397,21 @@ next_loop_unlocked:
thr->outbuf->allocated, LZMA_RUN);
if (ret == LZMA_OK) {
- if (partial_update != PARTIAL_DISABLED) {
- // The main thread uses thr->mutex to change from
- // PARTIAL_DISABLED to PARTIAL_START. The main thread
- // doesn't care about this variable after that so we
- // can safely change it here to PARTIAL_ENABLED
- // without a mutex.
- thr->partial_update = PARTIAL_ENABLED;
+ if (partial_update_enabled) {
+ // Remember that we have done at least one partial
+ // update. After the first update we won't do updates
+ // unless we have made progress.
+ thr->partial_update_started = true;
// The main thread is reading decompressed data
// from thr->outbuf. Tell the main thread about
// our progress.
//
// NOTE: It's possible that we consumed input without
- // producing any new output so it's possible that
- // only in_pos has changed. In case of PARTIAL_START
- // it is possible that neither in_pos nor out_pos has
- // changed.
+ // producing any new output so it's possible that only
+ // in_pos has changed. If thr->partial_update_started
+ // was false, it is possible that neither in_pos nor
+ // out_pos has changed.
mythread_sync(thr->coder->mutex) {
thr->outbuf->pos = thr->out_pos;
thr->outbuf->decoder_in_pos = thr->in_pos;
@@ -645,7 +633,8 @@ get_thread(struct lzma_stream_coder *coder, const lzma_allocator *allocator)
coder->thr->progress_in = 0;
coder->thr->progress_out = 0;
- coder->thr->partial_update = PARTIAL_DISABLED;
+ coder->thr->partial_update_enabled = false;
+ coder->thr->partial_update_started = false;
return LZMA_OK;
}
@@ -816,12 +805,12 @@ read_output_and_wait(struct lzma_stream_coder *coder,
// keeps calling lzma_code() without providing more
// input, it will eventually get LZMA_BUF_ERROR.
//
- // NOTE: We can read partial_update and in_filled
- // without thr->mutex as only the main thread
+ // NOTE: We can read partial_update_enabled and
+ // in_filled without thr->mutex as only the main thread
// modifies these variables. decoder_in_pos requires
// coder->mutex which we are already holding.
- if (coder->thr != NULL && coder->thr->partial_update
- != PARTIAL_DISABLED) {
+ if (coder->thr != NULL &&
+ coder->thr->partial_update_enabled) {
// There is exactly one outbuf in the queue.
assert(coder->thr->outbuf == coder->outq.head);
assert(coder->thr->outbuf == coder->outq.tail);
diff --git a/src/liblzma/common/vli_decoder.c b/src/liblzma/common/vli_decoder.c
index 3254ccc35bde..7fa5f47e10c4 100644
--- a/src/liblzma/common/vli_decoder.c
+++ b/src/liblzma/common/vli_decoder.c
@@ -38,7 +38,7 @@ lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos,
// Validate the arguments.
if (*vli_pos >= LZMA_VLI_BYTES_MAX
|| (*vli >> (*vli_pos * 7)) != 0)
- return LZMA_PROG_ERROR;;
+ return LZMA_PROG_ERROR;
if (*in_pos >= in_size)
return LZMA_BUF_ERROR;