// File: /workspace/github_c_makefile_star2_O1/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 $0x18, %rsp
movq %r9, 0x10(%rsp)
movq %r8, 0x8(%rsp)
movq %rcx, %rbx
movq %rdx, %r13
movq %rsi, %r14
movq %rdi, %r15
movl 0x50(%rsp), %ebp
leaq 0x38(%rdi), %r12
movq %r12, %rdi
callq 0x4750
cmpl $0x0, 0x40(%r14)
je 0x37f87
cmpl $0x1, %ebp
je 0x37f96
jmp 0x37fae
cmpl $0x1, %ebp
jne 0x37fae
movl 0x28(%r14), %eax
cmpl %eax, 0x44(%r14)
jl 0x37fae
movq %r12, %rdi
callq 0x4340
callq 0x4050
movl $0xb, (%rax)
jmp 0x3807d
movq %r12, (%rsp)
movl $0x40, %edi
callq 0x4680
testq %rax, %rax
je 0x38074
movq %rax, %r12
movq %r13, (%rax)
movq %rbx, 0x8(%rax)
movq 0x8(%rsp), %rax
movq %rax, 0x10(%r12)
movq 0x10(%rsp), %rax
movq %rax, 0x18(%r12)
movq $0x0, 0x20(%r12)
movq %r15, 0x28(%r12)
movq %r14, 0x30(%r12)
movq 0x38(%r14), %rax
leaq 0x1(%rax), %rcx
movq %rcx, 0x38(%r14)
movq %rax, 0x38(%r12)
cmpl $0x0, 0x50(%rsp)
je 0x38029
incl 0x4(%r15)
incl 0x44(%r14)
movq 0x10(%r14), %rcx
testq %rcx, %rcx
je 0x38084
leaq 0x10(%r14), %rax
movq %r12, 0x20(%rcx)
jmp 0x3808c
leaq 0x90(%r14), %rbx
movl 0x40(%r14), %eax
testl %eax, %eax
jne 0x38042
movl 0x44(%r14), %ecx
cmpl 0x28(%r14), %ecx
jl 0x38061
cmpl $0x0, 0x50(%r14)
jne 0x38061
cmpl $0x0, 0x58(%r14)
jne 0x38061
movq (%r14), %rsi
addq $0x38, %rsi
movq %rbx, %rdi
callq 0x47c0
jmp 0x38030
testl %eax, %eax
jne 0x3806c
cmpl $0x0, 0x50(%r14)
je 0x380b8
movq %r12, %rdi
callq 0x45c0
movq (%rsp), %rdi
callq 0x4340
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x380a9
movq %r12, 0x10(%r14)
leaq 0x8(%r14), %rax
movq %r12, (%rax)
cmpl $0x0, 0x50(%r14)
jne 0x3809e
movq %r14, %rdi
callq 0x380e2
movq (%rsp), %rdi
callq 0x4340
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x0, 0x58(%r14)
je 0x3800e
movl $0x0, 0x58(%r14)
jmp 0x3800e