xz: Fix semi-busy-waiting in xz --flush-timeout.

When input blocked, xz --flush-timeout=1 would wake up every
millisecond and initiate flushing which would have nothing to
flush and thus would just waste CPU time. The fix disables the
timeout when no input has been seen since the previous flush.
This commit is contained in:
Lasse Collin 2020-01-26 14:13:42 +02:00
parent dcca70fe9f
commit 5a49e081a0
3 changed files with 19 additions and 4 deletions

View File

@ -729,6 +729,10 @@ coder_normal(file_pair *pair)
// Set the time of the most recent flushing. // Set the time of the most recent flushing.
mytime_set_flush_time(); mytime_set_flush_time();
// Mark that we haven't seen any new input
// since the previous flush.
pair->src_has_seen_input = false;
} else { } else {
// Start a new Block after LZMA_FULL_BARRIER. // Start a new Block after LZMA_FULL_BARRIER.
if (opt_block_list == NULL) { if (opt_block_list == NULL) {

View File

@ -749,6 +749,7 @@ io_open_src(const char *src_name)
.src_fd = -1, .src_fd = -1,
.dest_fd = -1, .dest_fd = -1,
.src_eof = false, .src_eof = false,
.src_has_seen_input = false,
.dest_try_sparse = false, .dest_try_sparse = false,
.dest_pending_sparse = 0, .dest_pending_sparse = 0,
}; };
@ -1133,10 +1134,15 @@ io_read(file_pair *pair, io_buf *buf, size_t size)
#ifndef TUKLIB_DOSLIKE #ifndef TUKLIB_DOSLIKE
if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) { if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) {
const io_wait_ret ret = io_wait(pair, // Disable the flush-timeout if no input has
mytime_get_flush_timeout(), // been seen since the previous flush and thus
true); // there would be nothing to flush after the
switch (ret) { // timeout expires (avoids busy waiting).
const int timeout = pair->src_has_seen_input
? mytime_get_flush_timeout()
: -1;
switch (io_wait(pair, timeout, true)) {
case IO_WAIT_MORE: case IO_WAIT_MORE:
continue; continue;
@ -1160,6 +1166,7 @@ io_read(file_pair *pair, io_buf *buf, size_t size)
} }
pos += (size_t)(amount); pos += (size_t)(amount);
pair->src_has_seen_input = true;
} }
return pos; return pos;

View File

@ -49,6 +49,10 @@ typedef struct {
/// True once end of the source file has been detected. /// True once end of the source file has been detected.
bool src_eof; bool src_eof;
/// For --flush-timeout: True if at least one byte has been read
/// since the previous flush or the start of the file.
bool src_has_seen_input;
/// If true, we look for long chunks of zeros and try to create /// If true, we look for long chunks of zeros and try to create
/// a sparse file. /// a sparse file.
bool dest_try_sparse; bool dest_try_sparse;