// File: /workspace/github_c_makefile_star2_O0/madler[P]pigz/pigz.c
// Function: parallel_compress
local void parallel_compress(void) {
    long seq;                       // sequence number
    struct space *curr;             // input data to compress
    struct space *next;             // input data that follows curr
    struct space *hold;             // input data that follows next
    struct space *dict;             // dictionary for next compression
    struct job *job;                // job for compress, then write
    int more;                       // true if more input to read
    unsigned hash;                  // hash for rsyncable
    unsigned char *scan;            // next byte to compute hash on
    unsigned char *end;             // after end of data to compute hash on
    unsigned char *last;            // position after last hit
    size_t left;                    // last hit in curr to end of curr
    size_t len;                     // for various length computations

    // if first time or after an option change, setup the job lists
    setup_jobs();

    // start write thread
    writeth = launch(write_thread, NULL);

    // read from input and start compress threads (write thread will pick up
    // the output of the compress threads)
    seq = 0;
    next = get_space(&in_pool);
    next->len = readn(g.ind, next->buf, next->size);
    hold = NULL;
    dict = NULL;
    scan = next->buf;
    hash = RSYNCHIT;
    left = 0;
    do {
        // create a new job
        job = alloc(NULL, sizeof(struct job));
        job->calc = new_lock(0);

        // update input spaces
        curr = next;
        next = hold;
        hold = NULL;

        // get more input if we don't already have some
        if (next == NULL) {
            next = get_space(&in_pool);
            next->len = readn(g.ind, next->buf, next->size);
        }

        // if rsyncable, generate block lengths and prepare curr for job to
        // likely have less than size bytes (up to the last hash hit)
        job->lens = NULL;
        if (g.rsync && curr->len) {
            // compute the hash function starting where we last left off to
            // cover either size bytes or to EOF, whichever is less, through
            // the data in curr (and in the next loop, through next) -- save
            // the block lengths resulting from the hash hits in the job->lens
            // list
            if (left == 0) {
                // scan is in curr
                last = curr->buf;
                end = curr->buf + curr->len;
                while (scan < end) {
                    hash = ((hash << 1) ^ *scan++) & RSYNCMASK;
                    if (hash == RSYNCHIT) {
                        len = (size_t)(scan - last);
                        append_len(job, len);
                        last = scan;
                    }
                }

                // continue scan in next
                left = (size_t)(scan - last);
                scan = next->buf;
            }

            // scan in next for enough bytes to fill curr, or what is available
            // in next, whichever is less (if next isn't full, then we're at
            // the end of the file) -- the bytes in curr since the last hit,
            // stored in left, counts towards the size of the first block
            last = next->buf;
            len = curr->size - curr->len;
            if (len > next->len)
                len = next->len;
            end = next->buf + len;
            while (scan < end) {
                hash = ((hash << 1) ^ *scan++) & RSYNCMASK;
                if (hash == RSYNCHIT) {
                    len = (size_t)(scan - last) + left;
                    left = 0;
                    append_len(job, len);
                    last = scan;
                }
            }
            append_len(job, 0);

            // create input in curr for job up to last hit or entire buffer if
            // no hits at all -- save remainder in next and possibly hold
            len = (size_t)((job->lens->len == 1 ? scan : last) - next->buf);
            if (len) {
                // got hits in next, or no hits in either -- copy to curr
                memcpy(curr->buf + curr->len, next->buf, len);
                curr->len += len;
                memmove(next->buf, next->buf + len, next->len - len);
                next->len -= len;
                scan -= len;
                left = 0;
            }
            else if (job->lens->len != 1 && left && next->len) {
                // had hits in curr, but none in next, and last hit in curr
                // wasn't right at the end, so we have input there to save --
                // use curr up to the last hit, save the rest, moving next to
                // hold
                hold = next;
                next = get_space(&in_pool);
                memcpy(next->buf, curr->buf + (curr->len - left), left);
                next->len = left;
                curr->len -= left;
            }
            else {
                // else, last match happened to be right at the end of curr, or
                // we're at the end of the input compressing the rest
                left = 0;
            }
        }

        // compress curr->buf to curr->len -- compress thread will drop curr
        job->in = curr;

        // set job->more if there is more to compress after curr
        more = next->len != 0;
        job->more = more;

        // provide dictionary for this job, prepare dictionary for next job
        job->out = dict;
        if (more && g.setdict) {
            if (curr->len >= DICT || job->out == NULL) {
                dict = curr;
                use_space(dict);
            }
            else {
                dict = get_space(&dict_pool);
                len = DICT - curr->len;
                memcpy(dict->buf, job->out->buf + (job->out->len - len), len);
                memcpy(dict->buf + len, curr->buf, curr->len);
                dict->len = DICT;
            }
        }

        // preparation of job is complete
        job->seq = seq;
        Trace(("-- read #%ld%s", seq, more ? "" : " (last)"));
        if (++seq < 1)
            throw(ERANGE, "overflow");

        // start another compress thread if needed
        if (cthreads < seq && cthreads < g.procs) {
            (void)launch(compress_thread, NULL);
            cthreads++;
        }

        // put job at end of compress list, let all the compressors know
        possess(compress_have);
        job->next = NULL;
        *compress_tail = job;
        compress_tail = &(job->next);
        twist(compress_have, BY, +1);
    } while (more);
    drop_space(next);

    // wait for the write thread to complete (we leave the compress threads out
    // there and waiting in case there is another stream to compress)
    join(writeth);
    writeth = NULL;
    Trace(("-- write thread joined"));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
callq 0xe830
leaq 0x3bdc(%rip), %rdi      # 0xe930
xorl %eax, %eax
movl %eax, %esi
leaq 0x114eb(%rip), %rdx     # 0x1c24a
movl $0x82d, %ecx            # imm = 0x82D
callq 0x11c90
movq %rax, 0x38bf0(%rip)     # 0x43960
movq $0x0, -0x8(%rbp)
leaq 0x38be9(%rip), %rdi     # 0x43968
callq 0xee00
movq %rax, -0x18(%rbp)
movl 0x18a02(%rip), %edi     # 0x23790
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0xcf80
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movl $0x7ff, -0x38(%rbp)     # imm = 0x7FF
movq $0x0, -0x58(%rbp)
xorl %eax, %eax
movl %eax, %edi
movl $0x40, %esi
callq 0xac60
movq %rax, -0x30(%rbp)
xorl %eax, %eax
movl %eax, %edi
leaq 0x11454(%rip), %rsi     # 0x1c24a
movl $0x83c, %edx            # imm = 0x83C
callq 0x116a0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xae60
leaq 0x38b37(%rip), %rdi     # 0x43968
callq 0xee00
movq %rax, -0x18(%rbp)
movl 0x18950(%rip), %edi     # 0x23790
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0xcf80
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x20(%rax)
cmpl $0x0, 0x189b9(%rip)     # 0x2382c
je 0xb13c
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0xb13c
cmpq $0x0, -0x58(%rbp)
jne 0xaf28
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x18(%rcx), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0xaf0d
movl -0x38(%rbp), %eax
shll %eax
movq -0x40(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x40(%rbp)
movzbl (%rcx), %ecx
xorl %ecx, %eax
andl $0xfff, %eax            # imm = 0xFFF
movl %eax, -0x38(%rbp)
cmpl $0x7ff, -0x38(%rbp)     # imm = 0x7FF
jne 0xaf0b
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0xefe0
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0xaeb3
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rcx
subq 0x18(%rcx), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jbe 0xaf62
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0xafd8
movl -0x38(%rbp), %eax
shll %eax
movq -0x40(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x40(%rbp)
movzbl (%rcx), %ecx
xorl %ecx, %eax
andl $0xfff, %eax            # imm = 0xFFF
movl %eax, -0x38(%rbp)
cmpl $0x7ff, -0x38(%rbp)     # imm = 0x7FF
jne 0xafd6
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rcx, %rax
addq -0x58(%rbp), %rax
movq %rax, -0x60(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x30(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0xefe0
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0xaf72
movq -0x30(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xefe0
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x1, 0x18(%rax)
jne 0xaffe
movq -0x40(%rbp), %rax
movq %rax, -0x68(%rbp)
jmp 0xb006
movq -0x50(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x8(%rcx), %rcx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0xb0ae
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rax
addq 0x18(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x60(%rbp), %rdx
callq 0x3360
movq -0x60(%rbp), %rcx
movq -0x10(%rbp), %rax
addq 0x18(%rax), %rcx
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
addq -0x60(%rbp), %rsi
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdx
subq -0x60(%rbp), %rdx
callq 0x3490
movq -0x60(%rbp), %rdx
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x18(%rax)
movq -0x60(%rbp), %rdx
movq -0x40(%rbp), %rax
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x58(%rbp)
jmp 0xb13a
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x1, 0x18(%rax)
je 0xb130
cmpq $0x0, -0x58(%rbp)
je 0xb130
movq -0x18(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0xb130
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
leaq 0x3888a(%rip), %rdi     # 0x43968
callq 0xee00
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
subq -0x58(%rbp), %rax
addq %rax, %rsi
movq -0x58(%rbp), %rdx
callq 0x3360
movq -0x58(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x58(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x18(%rax)
jmp 0xb138
movq $0x0, -0x58(%rbp)
jmp 0xb13a
jmp 0xb13c
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0x18(%rax)
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
cmpl $0x0, -0x34(%rbp)
je 0xb235
cmpl $0x0, 0x186b1(%rip)     # 0x23834
je 0xb235
movq -0x10(%rbp), %rax
cmpq $0x8000, 0x18(%rax)     # imm = 0x8000
jae 0xb1a2
movq -0x30(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0xb1b5
movq -0x10(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0xf260
jmp 0xb233
leaq 0x387cc(%rip), %rdi     # 0x43988
callq 0xee00
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rcx
movl $0x8000, %eax           # imm = 0x8000
subq 0x18(%rcx), %rax
movq %rax, -0x60(%rbp)
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
subq -0x60(%rbp), %rax
addq %rax, %rsi
movq -0x60(%rbp), %rdx
callq 0x3360
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rdi
addq -0x60(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdx
callq 0x3360
movq -0x28(%rbp), %rax
movq $0x8000, 0x18(%rax)     # imm = 0x8000
jmp 0xb235
movq -0x8(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x8(%rbp)
cmpq $0x1, %rax
jge 0xb269
movl $0x22, %edi
leaq 0x121bf(%rip), %rsi     # 0x1d41d
xorl %eax, %eax
movl %eax, %edx
movb $0x0, %al
callq 0x122d0
movslq 0x38738(%rip), %rax     # 0x439a8
cmpq -0x8(%rbp), %rax
jge 0xb2af
movl 0x3872c(%rip), %eax     # 0x439a8
cmpl 0x185ae(%rip), %eax     # 0x23830
jge 0xb2af
leaq 0x4065(%rip), %rdi      # 0xf2f0
xorl %eax, %eax
movl %eax, %esi
leaq 0x10fb4(%rip), %rdx     # 0x1c24a
movl $0x8b5, %ecx            # imm = 0x8B5
callq 0x11c90
movl 0x38702(%rip), %eax     # 0x439a8
addl $0x1, %eax
movl %eax, 0x386f9(%rip)     # 0x439a8
movq 0x386fa(%rip), %rdi     # 0x439b0
leaq 0x10f8d(%rip), %rsi     # 0x1c24a
movl $0x8ba, %edx            # imm = 0x8BA
callq 0x11900
movq -0x30(%rbp), %rax
movq $0x0, 0x38(%rax)
movq -0x30(%rbp), %rcx
movq 0x386da(%rip), %rax     # 0x439b8
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
addq $0x38, %rax
movq %rax, 0x386c8(%rip)     # 0x439b8
movq 0x386b9(%rip), %rdi     # 0x439b0
movl $0x1, %esi
movl $0x1, %edx
leaq 0x10f42(%rip), %rcx     # 0x1c24a
movl $0x8be, %r8d            # imm = 0x8BE
callq 0x119a0
cmpl $0x0, -0x34(%rbp)
jne 0xadd9
movq -0x18(%rbp), %rdi
callq 0x10160
movq 0x38633(%rip), %rdi     # 0x43960
leaq 0x10f16(%rip), %rsi     # 0x1c24a
movl $0x8c4, %edx            # imm = 0x8C4
callq 0x11ec0
movq $0x0, 0x38617(%rip) # 0x43960
addq $0x70, %rsp
popq %rbp
retq
nop