aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/common/stream_encoder_mt.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2016-11-21 20:24:50 +0200
committerLasse Collin <lasse.collin@tukaani.org>2016-11-21 20:24:50 +0200
commitd4a0462abe5478193521c14625e1c81fead87f9f (patch)
tree586031c1e9a515e105cfab17dc897d63b1395dd3 /src/liblzma/common/stream_encoder_mt.c
parentUpdate THANKS. (diff)
downloadxz-d4a0462abe5478193521c14625e1c81fead87f9f.tar.xz
liblzma: Avoid multiple definitions of lzma_coder structures.
Only one definition was visible in a translation unit. It avoided a few casts and temp variables but seems that this hack doesn't work with link-time optimizations in compilers as it's not C99/C11 compliant. Fixes: http://www.mail-archive.com/xz-devel@tukaani.org/msg00279.html
Diffstat (limited to '')
-rw-r--r--src/liblzma/common/stream_encoder_mt.c124
1 files changed, 68 insertions, 56 deletions
diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
index 9780ed04..2efe44c2 100644
--- a/src/liblzma/common/stream_encoder_mt.c
+++ b/src/liblzma/common/stream_encoder_mt.c
@@ -44,6 +44,7 @@ typedef enum {
} worker_state;
+typedef struct lzma_stream_coder_s lzma_stream_coder;
typedef struct worker_thread_s worker_thread;
struct worker_thread_s {
@@ -65,7 +66,7 @@ struct worker_thread_s {
/// Pointer to the main structure is needed when putting this
/// thread back to the stack of free threads.
- lzma_coder *coder;
+ lzma_stream_coder *coder;
/// The allocator is set by the main thread. Since a copy of the
/// pointer is kept here, the application must not change the
@@ -96,7 +97,7 @@ struct worker_thread_s {
};
-struct lzma_coder_s {
+struct lzma_stream_coder_s {
enum {
SEQ_STREAM_HEADER,
SEQ_BLOCK,
@@ -417,7 +418,7 @@ worker_start(void *thr_ptr)
/// Make the threads stop but not exit. Optionally wait for them to stop.
static void
-threads_stop(lzma_coder *coder, bool wait_for_threads)
+threads_stop(lzma_stream_coder *coder, bool wait_for_threads)
{
// Tell the threads to stop.
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
@@ -446,7 +447,7 @@ threads_stop(lzma_coder *coder, bool wait_for_threads)
/// Stop the threads and free the resources associated with them.
/// Wait until the threads have exited.
static void
-threads_end(lzma_coder *coder, const lzma_allocator *allocator)
+threads_end(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
mythread_sync(coder->threads[i].mutex) {
@@ -468,7 +469,8 @@ threads_end(lzma_coder *coder, const lzma_allocator *allocator)
/// Initialize a new worker_thread structure and create a new thread.
static lzma_ret
-initialize_new_thread(lzma_coder *coder, const lzma_allocator *allocator)
+initialize_new_thread(lzma_stream_coder *coder,
+ const lzma_allocator *allocator)
{
worker_thread *thr = &coder->threads[coder->threads_initialized];
@@ -510,7 +512,7 @@ error_mutex:
static lzma_ret
-get_thread(lzma_coder *coder, const lzma_allocator *allocator)
+get_thread(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
// If there are no free output subqueues, there is no
// point to try getting a thread.
@@ -548,7 +550,7 @@ get_thread(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
-stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
+stream_encode_in(lzma_stream_coder *coder, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, lzma_action action)
{
@@ -616,7 +618,7 @@ stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
/// Wait until more input can be consumed, more output can be read, or
/// an optional timeout is reached.
static bool
-wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
+wait_for_work(lzma_stream_coder *coder, mythread_condtime *wait_abs,
bool *has_blocked, bool has_input)
{
if (coder->timeout != 0 && !*has_blocked) {
@@ -662,11 +664,13 @@ wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
static lzma_ret
-stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
+stream_encode_mt(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
+ lzma_stream_coder *coder = coder_ptr;
+
switch (coder->sequence) {
case SEQ_STREAM_HEADER:
lzma_bufcpy(coder->header, &coder->header_pos,
@@ -834,8 +838,10 @@ stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
static void
-stream_encoder_mt_end(lzma_coder *coder, const lzma_allocator *allocator)
+stream_encoder_mt_end(void *coder_ptr, const lzma_allocator *allocator)
{
+ lzma_stream_coder *coder = coder_ptr;
+
// Threads must be killed before the output queue can be freed.
threads_end(coder, allocator);
lzma_outq_end(&coder->outq, allocator);
@@ -907,10 +913,12 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
static void
-get_progress(lzma_coder *coder, uint64_t *progress_in, uint64_t *progress_out)
+get_progress(void *coder_ptr, uint64_t *progress_in, uint64_t *progress_out)
{
+ lzma_stream_coder *coder = coder_ptr;
+
// Lock coder->mutex to prevent finishing threads from moving their
- // progress info from the worker_thread structure to lzma_coder.
+ // progress info from the worker_thread structure to lzma_stream_coder.
mythread_sync(coder->mutex) {
*progress_in = coder->progress_in;
*progress_out = coder->progress_out;
@@ -962,24 +970,27 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
return LZMA_UNSUPPORTED_CHECK;
// Allocate and initialize the base structure if needed.
- if (next->coder == NULL) {
- next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
- if (next->coder == NULL)
+ lzma_stream_coder *coder = next->coder;
+ if (coder == NULL) {
+ coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);
+ if (coder == NULL)
return LZMA_MEM_ERROR;
+ next->coder = coder;
+
// For the mutex and condition variable initializations
// the error handling has to be done here because
// stream_encoder_mt_end() doesn't know if they have
// already been initialized or not.
- if (mythread_mutex_init(&next->coder->mutex)) {
- lzma_free(next->coder, allocator);
+ if (mythread_mutex_init(&coder->mutex)) {
+ lzma_free(coder, allocator);
next->coder = NULL;
return LZMA_MEM_ERROR;
}
- if (mythread_cond_init(&next->coder->cond)) {
- mythread_mutex_destroy(&next->coder->mutex);
- lzma_free(next->coder, allocator);
+ if (mythread_cond_init(&coder->cond)) {
+ mythread_mutex_destroy(&coder->mutex);
+ lzma_free(coder, allocator);
next->coder = NULL;
return LZMA_MEM_ERROR;
}
@@ -989,76 +1000,76 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
next->get_progress = &get_progress;
// next->update = &stream_encoder_mt_update;
- next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
- next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
- next->coder->index = NULL;
- memzero(&next->coder->outq, sizeof(next->coder->outq));
- next->coder->threads = NULL;
- next->coder->threads_max = 0;
- next->coder->threads_initialized = 0;
+ coder->filters[0].id = LZMA_VLI_UNKNOWN;
+ coder->index_encoder = LZMA_NEXT_CODER_INIT;
+ coder->index = NULL;
+ memzero(&coder->outq, sizeof(coder->outq));
+ coder->threads = NULL;
+ coder->threads_max = 0;
+ coder->threads_initialized = 0;
}
// Basic initializations
- next->coder->sequence = SEQ_STREAM_HEADER;
- next->coder->block_size = (size_t)(block_size);
- next->coder->thread_error = LZMA_OK;
- next->coder->thr = NULL;
+ coder->sequence = SEQ_STREAM_HEADER;
+ coder->block_size = (size_t)(block_size);
+ coder->thread_error = LZMA_OK;
+ coder->thr = NULL;
// Allocate the thread-specific base structures.
assert(options->threads > 0);
- if (next->coder->threads_max != options->threads) {
- threads_end(next->coder, allocator);
+ if (coder->threads_max != options->threads) {
+ threads_end(coder, allocator);
- next->coder->threads = NULL;
- next->coder->threads_max = 0;
+ coder->threads = NULL;
+ coder->threads_max = 0;
- next->coder->threads_initialized = 0;
- next->coder->threads_free = NULL;
+ coder->threads_initialized = 0;
+ coder->threads_free = NULL;
- next->coder->threads = lzma_alloc(
+ coder->threads = lzma_alloc(
options->threads * sizeof(worker_thread),
allocator);
- if (next->coder->threads == NULL)
+ if (coder->threads == NULL)
return LZMA_MEM_ERROR;
- next->coder->threads_max = options->threads;
+ coder->threads_max = options->threads;
} else {
// Reuse the old structures and threads. Tell the running
// threads to stop and wait until they have stopped.
- threads_stop(next->coder, true);
+ threads_stop(coder, true);
}
// Output queue
- return_if_error(lzma_outq_init(&next->coder->outq, allocator,
+ return_if_error(lzma_outq_init(&coder->outq, allocator,
outbuf_size_max, options->threads));
// Timeout
- next->coder->timeout = options->timeout;
+ coder->timeout = options->timeout;
// Free the old filter chain and copy the new one.
- for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
- lzma_free(next->coder->filters[i].options, allocator);
+ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+ lzma_free(coder->filters[i].options, allocator);
return_if_error(lzma_filters_copy(
- filters, next->coder->filters, allocator));
+ filters, coder->filters, allocator));
// Index
- lzma_index_end(next->coder->index, allocator);
- next->coder->index = lzma_index_init(allocator);
- if (next->coder->index == NULL)
+ lzma_index_end(coder->index, allocator);
+ coder->index = lzma_index_init(allocator);
+ if (coder->index == NULL)
return LZMA_MEM_ERROR;
// Stream Header
- next->coder->stream_flags.version = 0;
- next->coder->stream_flags.check = options->check;
+ coder->stream_flags.version = 0;
+ coder->stream_flags.check = options->check;
return_if_error(lzma_stream_header_encode(
- &next->coder->stream_flags, next->coder->header));
+ &coder->stream_flags, coder->header));
- next->coder->header_pos = 0;
+ coder->header_pos = 0;
// Progress info
- next->coder->progress_in = 0;
- next->coder->progress_out = LZMA_STREAM_HEADER_SIZE;
+ coder->progress_in = 0;
+ coder->progress_out = LZMA_STREAM_HEADER_SIZE;
return LZMA_OK;
}
@@ -1111,7 +1122,8 @@ lzma_stream_encoder_mt_memusage(const lzma_mt *options)
return UINT64_MAX;
// Sum them with overflow checking.
- uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
+ uint64_t total_memusage = LZMA_MEMUSAGE_BASE
+ + sizeof(lzma_stream_coder)
+ options->threads * sizeof(worker_thread);
if (UINT64_MAX - total_memusage < inbuf_memusage)