// File: /workspace/github_c_makefile_star2_O0/samtools[P]htslib/thread_pool.c
// Function: wake_next_worker
static void wake_next_worker(hts_tpool_process *q, int locked) {
    if (!q) return;
    hts_tpool *p = q->p;
    if (!locked)
        pthread_mutex_lock(&p->pool_m);

    // Update the q_head to be this queue so we'll start processing
    // the queue we know to have results.
    assert(q->prev && q->next); // attached
    p->q_head = q;

    // Wake up if we have more jobs waiting than CPUs. This partially combats
    // CPU frequency scaling effects.  Starting too many threads and then
    // running out of jobs can cause each thread to have lots of start/stop
    // cycles, which then translates often to CPU frequency scaling
    // adjustments.  Instead it is better to only start as many threads as we
    // need to keep the throughput up, meaning some threads run flat out and
    // others are idle.
    //
    // This isn't perfect as we need to know how many can actually start,
    // rather than how many are waiting.  A limit on output queue size makes
    // these two figures different.
    assert(p->njobs >= q->n_input);

    int running = p->tsize - p->nwaiting;
    int sig = p->t_stack_top >= 0 && p->njobs > p->tsize - p->nwaiting
        && (q->n_processing < q->qsize - q->n_output);

//#define AVG_USAGE
#ifdef AVG_USAGE
    // Track average number of running threads and try to keep close.
    // We permit this to change, but slowly.  This avoids "boom and bust" cycles
    // where we read a lot of data, start a lot of jobs, then become idle again.
    // This way some threads run steadily and others dormant, which is better
    // for throughput.
    //
    // It's 50:50 if this is a good thing.  It helps some tasks quite significantly
    // while slightly hindering other (perhaps more usual) jobs.

    if (++p->n_count == 256) {
        p->n_count >>= 1;
        p->n_running >>= 1;
    }
    p->n_running += running;
    // Built in lag to avoid see-sawing.  Is this safe in all cases?
    if (sig && p->n_count >= 128 && running*p->n_count > p->n_running+1) sig=0;
#endif

    if (0) {
        printf("%d waiting, %d running, %d output, %d, arun %d => %d\t", p->njobs,
               running, q->n_output, q->qsize - q->n_output,
               p->n_running/p->n_count, sig);
        int i;
        for (i = 0; i < p->tsize; i++)
            putchar("x "[p->t_stack[i]]);
        putchar('\n');
    }

    if (sig)
        pthread_cond_signal(&p->t[p->t_stack_top].pending_c);

    if (!locked)
        pthread_mutex_unlock(&p->pool_m);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x4e5ab
jmp 0x4e6e0
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
cmpl $0x0, -0xc(%rbp)
jne 0x4e5c9
movq -0x18(%rbp), %rdi
addq $0x38, %rdi
callq 0x4730
movq -0x8(%rbp), %rax
cmpq $0x0, 0x128(%rax)
je 0x4e5e7
movq -0x8(%rbp), %rax
cmpq $0x0, 0x120(%rax)
je 0x4e5e7
jmp 0x4e606
leaq 0xa4f9b(%rip), %rdi     # 0xf3589
leaq 0xa4e49(%rip), %rsi     # 0xf343e
movl $0x296, %edx            # imm = 0x296
leaq 0xa4f9b(%rip), %rcx     # 0xf359c
callq 0x42e0
movq -0x8(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x44(%rcx), %eax
jl 0x4e624
jmp 0x4e643
leaq 0xa4fa1(%rip), %rdi     # 0xf35cc
leaq 0xa4e0c(%rip), %rsi     # 0xf343e
movl $0x2a4, %edx            # imm = 0x2A4
leaq 0xa4f5e(%rip), %rcx     # 0xf359c
callq 0x42e0
movq -0x18(%rbp), %rax
movl 0x18(%rax), %eax
movq -0x18(%rbp), %rcx
subl (%rcx), %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpl $0x0, 0x30(%rcx)
movb %al, -0x21(%rbp)
jl 0x4e69c
movq -0x18(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x18(%rbp), %rax
movl 0x18(%rax), %edx
movq -0x18(%rbp), %rax
subl (%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x21(%rbp)
jle 0x4e69c
movq -0x8(%rbp), %rax
movl 0x4c(%rax), %eax
movq -0x8(%rbp), %rcx
movl 0x28(%rcx), %ecx
movq -0x8(%rbp), %rdx
subl 0x48(%rdx), %ecx
cmpl %ecx, %eax
setl %al
movb %al, -0x21(%rbp)
movb -0x21(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
je 0x4e6cd
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x18(%rbp), %rax
movslq 0x30(%rax), %rax
imulq $0x48, %rax, %rax
addq %rax, %rdi
addq $0x18, %rdi
callq 0x4040
cmpl $0x0, -0xc(%rbp)
jne 0x4e6e0
movq -0x18(%rbp), %rdi
addq $0x38, %rdi
callq 0x4330
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)