// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/thread_pool.c
// Function: hts_tpool_dispatch3
int hts_tpool_dispatch3(hts_tpool *p, hts_tpool_process *q,
                        void *(*exec_func)(void *arg), void *arg,
                        void (*job_cleanup)(void *arg),
                        void (*result_cleanup)(void *data),
                        int nonblock) {
    hts_tpool_job *j;

    pthread_mutex_lock(&p->pool_m);

    DBG_OUT(stderr, "Dispatching job for queue %p, serial %"PRId64"\n",
            q, q->curr_serial);

    if ((q->no_more_input || q->n_input >= q->qsize) && nonblock == 1) {
        pthread_mutex_unlock(&p->pool_m);
        errno = EAGAIN;
        return -1;
    }

    if (!(j = malloc(sizeof(*j)))) {
        pthread_mutex_unlock(&p->pool_m);
        return -1;
    }
    j->func = exec_func;
    j->arg = arg;
    j->job_cleanup = job_cleanup;
    j->result_cleanup = result_cleanup;
    j->next = NULL;
    j->p = p;
    j->q = q;
    j->serial = q->curr_serial++;

    if (nonblock == 0) {
        while ((q->no_more_input || q->n_input >= q->qsize) &&
               !q->shutdown && !q->wake_dispatch) {
            pthread_cond_wait(&q->input_not_full_c, &q->p->pool_m);
        }
        if (q->no_more_input || q->shutdown) {
            free(j);
            pthread_mutex_unlock(&p->pool_m);
            return -1;
        }
        if (q->wake_dispatch) {
            //fprintf(stderr, "Wake => non-block for this operation\n");
            q->wake_dispatch = 0;
        }
    }

    p->njobs++;    // total across all queues
    q->n_input++;  // queue specific

    if (q->input_tail) {
        q->input_tail->next = j;
        q->input_tail = j;
    } else {
        q->input_head = q->input_tail = j;
    }

    DBG_OUT(stderr, "Dispatched (serial %"PRId64")\n", j->serial);

    // Let a worker know we have data.
    // Keep incoming queue at 1 per running thread, so there is always
    // something waiting when they end their current task.  If we go above
    // this signal to start more threads (if available). This has the effect
    // of concentrating jobs to fewer cores when we are I/O bound, which in
    // turn benefits systems with auto CPU frequency scaling.
    if (!q->shutdown)
        wake_next_worker(q, 1);

    pthread_mutex_unlock(&p->pool_m);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r9, 0x20(%rsp)
movq %r8, 0x18(%rsp)
movq %rcx, 0x10(%rsp)
movq %rdx, %r13
movq %rsi, %r14
movl 0x60(%rsp), %ebx
movq %rdi, %rbp
leaq 0x38(%rdi), %r12
movq %r12, %rdi
callq 0x4750
movl 0x40(%r14), %r15d
testl %r15d, %r15d
je 0x36b53
cmpl $0x1, %ebx
je 0x36b62
jmp 0x36b7a
cmpl $0x1, %ebx
jne 0x36b7a
movl 0x28(%r14), %eax
cmpl %eax, 0x44(%r14)
jl 0x36b7a
movq %r12, %rdi
callq 0x4340
callq 0x4050
movl $0xb, (%rax)
jmp 0x36c7a
movq %r12, 0x8(%rsp)
movl $0x40, %edi
callq 0x4680
testq %rax, %rax
je 0x36c70
movq %rax, %r12
movq %r13, (%rax)
movq 0x10(%rsp), %rax
movq %rax, 0x8(%r12)
movq 0x18(%rsp), %rax
movq %rax, 0x10(%r12)
movq 0x20(%rsp), %rax
movq %rax, 0x18(%r12)
movq $0x0, 0x20(%r12)
movq %rbp, 0x28(%r12)
movq %r14, 0x30(%r12)
movq 0x38(%r14), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x38(%r14)
movq %rax, 0x38(%r12)
cmpl $0x0, 0x60(%rsp)
je 0x36c1f
incl 0x4(%rbp)
incl 0x44(%r14)
movq 0x10(%r14), %rax
leaq 0x20(%rax), %rcx
leaq 0x8(%r14), %rdx
testq %rax, %rax
cmoveq %rdx, %rcx
movq %r12, (%rcx)
movq %r12, 0x10(%r14)
cmpl $0x0, 0x50(%r14)
jne 0x36c11
movq %r14, %rdi
callq 0x36cb8
movq 0x8(%rsp), %rdi
callq 0x4340
xorl %eax, %eax
jmp 0x36c7f
leaq 0x90(%r14), %rbx
testl %r15d, %r15d
jne 0x36c35
movl 0x44(%r14), %eax
cmpl 0x28(%r14), %eax
jl 0x36c60
movl 0x50(%r14), %eax
testl %eax, %eax
jne 0x36c59
cmpl $0x0, 0x58(%r14)
jne 0x36c59
movq (%r14), %rsi
addq $0x38, %rsi
movq %rbx, %rdi
callq 0x47c0
movl 0x40(%r14), %r15d
jmp 0x36c26
testl %r15d, %r15d
jne 0x36c68
jmp 0x36c64
movl 0x50(%r14), %eax
testl %eax, %eax
je 0x36c8e
movq %r12, %rdi
callq 0x45c0
movq 0x8(%rsp), %rdi
callq 0x4340
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x0, 0x58(%r14)
je 0x36be1
movl $0x0, 0x58(%r14)
jmp 0x36be1