23 #define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)
187 mythread_sync(thr->
coder->mutex) {
189 thr->
coder->thread_error = ret;
191 mythread_cond_signal(&thr->
coder->cond);
208 .compressed_size = thr->
coder->outq.buf_size_max,
209 .uncompressed_size = thr->
coder->block_size,
238 const size_t out_size = thr->
coder->outq.buf_size_max;
241 mythread_sync(thr->
mutex) {
254 mythread_cond_wait(&thr->
cond, &thr->
mutex);
270 static const size_t in_chunk_max = 16384;
273 in_limit =
in_pos + in_chunk_max;
304 mythread_sync(thr->
mutex) {
306 mythread_cond_wait(&thr->
cond, &thr->
mutex);
345 static MYTHREAD_RET_TYPE
353 mythread_sync(thr->
mutex) {
359 mythread_cond_signal(&thr->
cond);
366 mythread_cond_wait(&thr->
cond, &thr->
mutex);
382 mythread_sync(thr->
mutex) {
385 mythread_cond_signal(&thr->
cond);
389 mythread_sync(thr->
coder->mutex) {
395 thr->
coder->progress_in
403 thr->
coder->threads_free = thr;
405 mythread_cond_signal(&thr->
coder->cond);
410 mythread_mutex_destroy(&thr->
mutex);
411 mythread_cond_destroy(&thr->
cond);
415 return MYTHREAD_RET_VALUE;
424 for (
uint32_t i = 0;
i < coder->threads_initialized; ++
i) {
425 mythread_sync(coder->threads[
i].mutex) {
427 mythread_cond_signal(&coder->threads[
i].cond);
431 if (!wait_for_threads)
435 for (
uint32_t i = 0;
i < coder->threads_initialized; ++
i) {
436 mythread_sync(coder->threads[
i].mutex) {
437 while (coder->threads[
i].state !=
THR_IDLE)
438 mythread_cond_wait(&coder->threads[
i].cond,
439 &coder->threads[
i].mutex);
452 for (
uint32_t i = 0;
i < coder->threads_initialized; ++
i) {
453 mythread_sync(coder->threads[
i].mutex) {
455 mythread_cond_signal(&coder->threads[
i].cond);
459 for (
uint32_t i = 0;
i < coder->threads_initialized; ++
i) {
460 int ret = mythread_join(coder->threads[
i].thread_id);
475 worker_thread *thr = &coder->threads[coder->threads_initialized];
481 if (mythread_mutex_init(&thr->
mutex))
484 if (mythread_cond_init(&thr->
cond))
497 ++coder->threads_initialized;
503 mythread_cond_destroy(&thr->
cond);
506 mythread_mutex_destroy(&thr->
mutex);
523 mythread_sync(coder->mutex) {
524 if (coder->threads_free !=
NULL) {
525 coder->thr = coder->threads_free;
526 coder->threads_free = coder->threads_free->next;
530 if (coder->thr ==
NULL) {
532 if (coder->threads_initialized == coder->threads_max)
541 mythread_sync(coder->thr->mutex) {
543 coder->thr->in_size = 0;
545 mythread_cond_signal(&coder->thr->cond);
559 if (coder->thr ==
NULL) {
562 if (coder->thr ==
NULL)
567 size_t thr_in_size = coder->thr->in_size;
569 &thr_in_size, coder->block_size);
577 const bool finish = thr_in_size == coder->block_size
580 bool block_error =
false;
582 mythread_sync(coder->thr->mutex) {
583 if (coder->thr->state ==
THR_IDLE) {
591 coder->thr->in_size = thr_in_size;
596 mythread_cond_signal(&coder->thr->cond);
603 mythread_sync(coder->mutex) {
604 ret = coder->thread_error;
622 bool *has_blocked,
bool has_input)
624 if (coder->timeout != 0 && !*has_blocked) {
634 mythread_condtime_set(wait_abs, &coder->cond, coder->timeout);
637 bool timed_out =
false;
639 mythread_sync(coder->mutex) {
647 while ((!has_input || coder->threads_free ==
NULL
650 && coder->thread_error ==
LZMA_OK
652 if (coder->timeout != 0)
653 timed_out = mythread_cond_timedwait(
654 &coder->cond, &coder->mutex,
657 mythread_cond_wait(&coder->cond,
675 case SEQ_STREAM_HEADER:
677 sizeof(coder->header),
679 if (coder->header_pos <
sizeof(coder->header))
682 coder->header_pos = 0;
694 bool has_blocked =
false;
695 mythread_condtime wait_abs;
698 mythread_sync(coder->mutex) {
700 ret = coder->thread_error;
715 ret = lzma_index_append(coder->
index,
799 coder->progress_out += lzma_index_size(coder->
index)
817 = lzma_index_size(coder->
index);
822 coder->
sequence = SEQ_STREAM_FOOTER;
827 case SEQ_STREAM_FOOTER:
829 sizeof(coder->header),
831 return coder->header_pos <
sizeof(coder->header)
855 mythread_cond_destroy(&coder->cond);
856 mythread_mutex_destroy(&coder->mutex);
894 *block_size =
options->block_size;
898 if (*block_size == 0)
908 if (*outbuf_size_max == 0)
922 mythread_sync(coder->mutex) {
924 *progress_out = coder->progress_out;
926 for (
size_t i = 0;
i < coder->threads_initialized; ++
i) {
927 mythread_sync(coder->threads[
i].mutex) {
929 *progress_out += coder->threads[
i]
951 &block_size, &outbuf_size_max));
953 #if SIZE_MAX < UINT64_MAX
969 if (!lzma_check_is_supported(
options->check))
985 if (mythread_mutex_init(&coder->mutex)) {
991 if (mythread_cond_init(&coder->cond)) {
992 mythread_mutex_destroy(&coder->mutex);
1006 memzero(&coder->outq,
sizeof(coder->outq));
1007 coder->threads =
NULL;
1008 coder->threads_max = 0;
1009 coder->threads_initialized = 0;
1013 coder->
sequence = SEQ_STREAM_HEADER;
1014 coder->block_size = (
size_t)(block_size);
1015 coder->thread_error =
LZMA_OK;
1020 if (coder->threads_max !=
options->threads) {
1023 coder->threads =
NULL;
1024 coder->threads_max = 0;
1026 coder->threads_initialized = 0;
1027 coder->threads_free =
NULL;
1032 if (coder->threads ==
NULL)
1035 coder->threads_max =
options->threads;
1044 outbuf_size_max,
options->threads));
1047 coder->timeout =
options->timeout;
1068 coder->header_pos = 0;
1071 coder->progress_in = 0;
1116 filters_memusage *=
options->threads;
1120 outbuf_size_max,
options->threads);
1129 if (
UINT64_MAX - total_memusage < inbuf_memusage)
1132 total_memusage += inbuf_memusage;
1134 if (
UINT64_MAX - total_memusage < filters_memusage)
1137 total_memusage += filters_memusage;
1139 if (
UINT64_MAX - total_memusage < outq_memusage)
1142 return total_memusage + outq_memusage;
static bool finish(void *user)
#define LZMA_CHECK_ID_MAX
Maximum valid Check ID.
const lzma_allocator lzma_vli unpadded_size
const lzma_allocator const uint8_t size_t uint8_t size_t * out_pos
const lzma_allocator const uint8_t size_t * in_pos
const lzma_allocator const uint8_t size_t in_size
const lzma_allocator * allocator
const lzma_allocator const uint8_t * in
const lzma_allocator const uint8_t size_t uint8_t * out
uint64_t lzma_block_buffer_bound64(uint64_t uncompressed_size)
Single-call .xz Block encoder.
lzma_ret lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, lzma_block *block)
const lzma_filter * filters
bool lzma_easy_preset(lzma_options_easy *opt_easy, uint32_t preset)
Preset handling for easy encoder and decoder.
#define LZMA_FILTERS_MAX
Maximum number of filters in a chain.
uint64_t lzma_mt_block_size(const lzma_filter *filters)
lzma_ret lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_index *i)
static const char struct stat static buf struct stat static buf static vhangup int options
assert(limit<=UINT32_MAX/2)
lzma_outbuf * lzma_outq_get_buf(lzma_outq *outq)
Get a new buffer.
void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator)
Free the memory associated with the output queue.
bool lzma_outq_is_readable(const lzma_outq *outq)
Test if there is data ready to be read.
lzma_ret lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_vli *restrict unpadded_size, lzma_vli *restrict uncompressed_size)
Read finished data.
uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
Calculate the memory usage of an output queue.
lzma_ret lzma_outq_init(lzma_outq *outq, const lzma_allocator *allocator, uint64_t buf_size_max, uint32_t threads)
Initialize an output queue.
Output queue handling in multithreaded coding.
static bool lzma_outq_has_buf(const lzma_outq *outq)
Test if there is at least one buffer free.
static bool lzma_outq_is_empty(const lzma_outq *outq)
Test if the queue is completely empty.
static lzma_ret stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_mt *options)
static void threads_stop(lzma_stream_coder *coder, bool wait_for_threads)
Make the threads stop but not exit. Optionally wait for them to stop.
static lzma_ret 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)
static worker_state worker_encode(worker_thread *thr, worker_state state)
static void stream_encoder_mt_end(void *coder_ptr, const lzma_allocator *allocator)
static lzma_ret get_thread(lzma_stream_coder *coder, const lzma_allocator *allocator)
struct lzma_stream_coder_s lzma_stream_coder
static void worker_error(worker_thread *thr, lzma_ret ret)
Tell the main thread that something has gone wrong.
@ THR_RUN
Encoding is in progress.
@ THR_IDLE
Waiting for work.
static void get_progress(void *coder_ptr, uint64_t *progress_in, uint64_t *progress_out)
static lzma_ret initialize_new_thread(lzma_stream_coder *coder, const lzma_allocator *allocator)
Initialize a new worker_thread structure and create a new thread.
static void threads_end(lzma_stream_coder *coder, const lzma_allocator *allocator)
static MYTHREAD_RET_TYPE worker_start(void *thr_ptr)
static bool wait_for_work(lzma_stream_coder *coder, mythread_condtime *wait_abs, bool *has_blocked, bool has_input)
static lzma_ret 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)
static lzma_ret get_options(const lzma_mt *options, lzma_options_easy *opt_easy, const lzma_filter **filters, uint64_t *block_size, uint64_t *outbuf_size_max)
#define LZMA_STREAM_HEADER_SIZE
Size of Stream Header and Stream Footer.
Custom functions for memory handling.
Options for the Block and Block Header encoders and decoders.
lzma_vli uncompressed_size
Uncompressed Size in bytes.
uint32_t header_size
Size of the Block Header field.
uint32_t version
Block format version.
void * options
Pointer to filter-specific options structure.
bool supported_actions[LZMA_ACTION_MAX+1]
Indicates which lzma_action values are allowed by next.code.
Hold data and function pointers of the next filter in the chain.
void(* get_progress)(void *coder, uint64_t *progress_in, uint64_t *progress_out)
lzma_code_function code
Pointer to function to do the actual coding.
void * coder
Pointer to coder-specific data.
lzma_filter filters[LZMA_FILTERS_MAX+1]
Output buffer for a single thread.
size_t size
Amount of data written to buf.
lzma_vli uncompressed_size
uint8_t * buf
Pointer to the output buffer of lzma_outq.buf_size_max bytes.
lzma_vli unpadded_size
Additional size information.
uint8_t header[LZMA_STREAM_HEADER_SIZE]
Buffer to hold Stream Header and Stream Footer.
enum lzma_stream_coder_s::@654 sequence
lzma_next_coder index_encoder
Index encoder.
lzma_outq outq
Output buffer queue for compressed data.
lzma_filter filters[LZMA_FILTERS_MAX+1]
The filter chain currently in use.
lzma_index * index
Index to hold sizes of the Blocks.
worker_thread * threads_free
lzma_ret thread_error
Error code from a worker thread.
worker_thread * threads
Array of allocated thread-specific structures.
uint32_t threads_initialized
lzma_stream_flags stream_flags
Stream Flags for encoding the Stream Header and Stream Footer.
size_t header_pos
Read position in header[].
lzma_next_coder index_encoder
lzma_index * index
Index to hold sizes of the Blocks.
enum lzma_stream_coder::@652 sequence
lzma_stream_flags stream_flags
Stream Flags from Stream Header.
lzma_filter filters[LZMA_FILTERS_MAX+1]
The filter chain currently in use.
Options for encoding/decoding Stream Header and Stream Footer.
uint32_t version
Stream Flags format version.
lzma_vli backward_size
Backward Size.
lzma_check check
Check ID.
Passing data to and from liblzma.
worker_thread * next
Next structure in the stack of free worker threads.
lzma_block block_options
Compression options for this Block.
uint64_t progress_in
Amount of uncompressed data that has already been compressed.
lzma_stream_coder * coder
lzma_next_coder block_encoder
Block encoder.
const lzma_allocator * allocator
uint64_t progress_out
Amount of compressed data that is ready.
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
#define LZMA_MEMUSAGE_BASE
#define return_if_error(expr)
Return if expression doesn't evaluate to LZMA_OK.
#define lzma_next_coder_init(func, next, allocator)
#define lzma_next_strm_init(func, strm,...)
void * lzma_alloc(size_t size, const lzma_allocator *allocator) lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
Allocates memory.
uint64_t uncompressed_size
uint64_t lzma_vli
Variable-length integer type.
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
lzma_ret
Return values used by several functions in liblzma.
@ LZMA_PROG_ERROR
Programming error.
@ LZMA_MEM_ERROR
Cannot allocate memory.
@ LZMA_STREAM_END
End of stream was reached.
@ LZMA_UNSUPPORTED_CHECK
Cannot calculate the integrity check.
@ LZMA_OPTIONS_ERROR
Invalid or unsupported options.
@ LZMA_OK
Operation completed successfully.
lzma_action
The ‘action’ argument for lzma_code()
@ LZMA_FINISH
Finish the coding operation.
@ LZMA_RUN
Continue coding.
@ LZMA_FULL_FLUSH
Finish encoding of the current Block.
@ LZMA_FULL_BARRIER
Finish encoding of the current Block.
void lzma_free(void *ptr, const lzma_allocator *allocator)
Frees memory.
size_t lzma_bufcpy(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)
void lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)