// File: /workspace/github_c_makefile_star2_O3/samtools[P]htslib/thread_pool.c
// Function: hts_tpool_init
hts_tpool *hts_tpool_init(int n) {
    int t_idx = 0;
    size_t stack_size = 0;
    pthread_attr_t pattr;
    int pattr_init_done = 0;
    hts_tpool *p = malloc(sizeof(*p));
    if (!p)
        return NULL;
    p->tsize = n;
    p->njobs = 0;
    p->nwaiting = 0;
    p->shutdown = 0;
    p->q_head = NULL;
    p->t_stack = NULL;
    p->n_count = 0;
    p->n_running = 0;
    p->t = malloc(n * sizeof(p->t[0]));
    if (!p->t) {
        free(p);
        return NULL;
    }
    p->t_stack = malloc(n * sizeof(*p->t_stack));
    if (!p->t_stack) {
        free(p->t);
        free(p);
        return NULL;
    }
    p->t_stack_top = -1;

    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&p->pool_m, &attr);
    pthread_mutexattr_destroy(&attr);

    pthread_mutex_lock(&p->pool_m);

    // Ensure new threads have a reasonably large stack.  On some platforms,
    // for example MacOS which defaults to 512Kb, this is not big enough
    // for some of the rANS codecs.

    if (pthread_attr_init(&pattr) < 0)
        goto cleanup;
    pattr_init_done = 1;
    if (pthread_attr_getstacksize(&pattr, &stack_size) < 0)
        goto cleanup;
    if (stack_size < HTS_MIN_THREAD_STACK) {
        if (pthread_attr_setstacksize(&pattr, HTS_MIN_THREAD_STACK) < 0)
            goto cleanup;
    }

    for (t_idx = 0; t_idx < n; t_idx++) {
        hts_tpool_worker *w = &p->t[t_idx];
        p->t_stack[t_idx] = 0;
        w->p = p;
        w->idx = t_idx;
        pthread_cond_init(&w->pending_c, NULL);
        if (0 != pthread_create(&w->tid, &pattr, tpool_worker, w))
            goto cleanup;
    }

    pthread_mutex_unlock(&p->pool_m);
    pthread_attr_destroy(&pattr);

    return p;

 cleanup: {
        // Any threads started will be waiting for p->pool_m, so we can
        // stop them cleanly by setting p->shutdown, releasing the mutex and
        // waiting for them to finish.
        int j;
        int save_errno = errno;
        hts_log_error("Couldn't start thread pool worker : %s",
                      strerror(errno));
        p->shutdown = 1;
        pthread_mutex_unlock(&p->pool_m);
        for (j = 0; j < t_idx; j++) {
            pthread_join(p->t[j].tid, NULL);
            pthread_cond_destroy(&p->t[j].pending_c);
        }
        pthread_mutex_destroy(&p->pool_m);
        if (pattr_init_done)
            pthread_attr_destroy(&pattr);
        free(p->t_stack);
        free(p->t);
        free(p);
        errno = save_errno;
        return NULL;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edi, %r15d
movq $0x0, 0x10(%rsp)
movl $0x78, %edi
callq 0x4680
testq %rax, %rax
je 0x3673a
movq %rax, %rbx
movl %r15d, 0x18(%rax)
xorl %eax, %eax
movq %rax, (%rbx)
movl $0x0, 0x8(%rbx)
movq %rax, 0x10(%rbx)
movq %rax, 0x28(%rbx)
movq %rax, 0x60(%rbx)
movslq %r15d, %r12
leaq (,%r12,8), %rax
leaq (%rax,%rax,8), %rdi
callq 0x4680
movq %rax, 0x20(%rbx)
testq %rax, %rax
je 0x36678
movq %rax, %r14
shlq $0x2, %r12
movq %r12, %rdi
callq 0x4680
movq %rax, 0x28(%rbx)
testq %rax, %rax
je 0x36670
movl $0xffffffff, 0x30(%rbx) # imm = 0xFFFFFFFF
leaq 0x1c(%rsp), %r12
movq %r12, %rdi
callq 0x4070
movq %r12, %rdi
movl $0x1, %esi
callq 0x4760
movq %rbx, %r13
addq $0x38, %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x4780
movq %r12, %rdi
callq 0x4770
movq %r13, %rdi
callq 0x4750
leaq 0x20(%rsp), %rdi
callq 0x45f0
xorl %r12d, %r12d
testl %eax, %eax
movl %eax, 0x4(%rsp)
js 0x3668a
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4440
testl %eax, %eax
js 0x3668a
cmpq $0x2fffff, 0x10(%rsp)   # imm = 0x2FFFFF
ja 0x365e7
leaq 0x20(%rsp), %rdi
movl $0x300000, %esi         # imm = 0x300000
callq 0x46a0
testl %eax, %eax
js 0x3668a
movq %r13, 0x8(%rsp)
testl %r15d, %r15d
jle 0x36657
movl %r15d, %r15d
movl $0x10, %r14d
xorl %r12d, %r12d
movq 0x20(%rbx), %rax
movq 0x28(%rbx), %rcx
leaq (%rax,%r14), %r13
leaq (%rax,%r14), %rbp
addq $-0x10, %rbp
movl $0x0, (%rcx,%r12,4)
movq %rbx, (%rbp)
movl %r12d, 0x8(%rbp)
leaq (%rax,%r14), %rdi
addq $0x8, %rdi
xorl %esi, %esi
callq 0x45d0
movq %r13, %rdi
leaq 0x20(%rsp), %rsi
leaq 0x10f(%rip), %rdx       # 0x3674e
movq %rbp, %rcx
callq 0x4920
testl %eax, %eax
jne 0x36685
incq %r12
addq $0x48, %r14
cmpq %r12, %r15
jne 0x365fd
movq 0x8(%rsp), %rdi
callq 0x4340
leaq 0x20(%rsp), %rdi
callq 0x4870
jmp 0x3673c
movq %r14, %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x45c0
jmp 0x3673a
movq 0x8(%rsp), %r13
callq 0x4050
movq %rax, %r15
movl (%rax), %ebp
movl %ebp, %edi
callq 0x4150
leaq 0x627ea(%rip), %rsi     # 0x98e8c
leaq 0x627f2(%rip), %rdx     # 0x98e9b
movl $0x1, %edi
movq %rax, %rcx
xorl %eax, %eax
callq 0x13de5
movl $0x1, 0x8(%rbx)
movq %r13, %rdi
callq 0x4340
testl %r12d, %r12d
je 0x36704
movl %r12d, %eax
shlq $0x3, %rax
leaq (%rax,%rax,8), %r14
xorl %r12d, %r12d
movq 0x20(%rbx), %rax
movq 0x10(%rax,%r12), %rdi
xorl %esi, %esi
callq 0x4410
movq 0x20(%rbx), %rax
leaq (%rax,%r12), %rdi
addq $0x18, %rdi
callq 0x49a0
addq $0x48, %r12
cmpq %r12, %r14
jne 0x366da
movq %r13, %rdi
callq 0x4590
cmpl $0x0, 0x4(%rsp)
js 0x3671d
leaq 0x20(%rsp), %rdi
callq 0x4870
movq 0x28(%rbx), %rdi
callq 0x45c0
movq 0x20(%rbx), %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x45c0
movl %ebp, (%r15)
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq