// File: /workspace/github_c_makefile_star2_O2/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
andq $0x0, 0x10(%rsp)
pushq $0x78
popq %rdi
callq 0x4680
testq %rax, %rax
je 0x2c4fb
movq %rax, %rbx
movl %r15d, 0x18(%rax)
andq $0x0, (%rax)
andl $0x0, 0x8(%rax)
andq $0x0, 0x10(%rax)
andq $0x0, 0x28(%rax)
andq $0x0, 0x60(%rax)
movslq %r15d, %r12
imulq $0x48, %r12, %rdi
callq 0x4680
movq %rax, 0x20(%rbx)
testq %rax, %rax
je 0x2c4f3
movq %rax, %r14
shlq $0x2, %r12
movq %r12, %rdi
callq 0x4680
movq %rax, 0x28(%rbx)
testq %rax, %rax
je 0x2c4eb
orl $-0x1, 0x30(%rbx)
leaq 0x1c(%rsp), %r12
movq %r12, %rdi
callq 0x4070
pushq $0x1
popq %rsi
movq %r12, %rdi
callq 0x4760
movq %rbx, %r14
addq $0x38, %r14
movq %r14, %rdi
movq %r12, %rsi
callq 0x4780
movq %r12, %rdi
callq 0x4770
movq %r14, (%rsp)
movq %r14, %rdi
callq 0x4750
leaq 0x20(%rsp), %rdi
callq 0x45f0
testl %eax, %eax
movl %eax, 0xc(%rsp)
js 0x2c43e
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x4440
testl %eax, %eax
js 0x2c43e
cmpq $0x2fffff, 0x10(%rsp)   # imm = 0x2FFFFF
ja 0x2c3d7
leaq 0x20(%rsp), %rdi
movl $0x300000, %esi         # imm = 0x300000
callq 0x46a0
testl %eax, %eax
js 0x2c43e
xorl %r12d, %r12d
testl %r15d, %r15d
cmovlel %r12d, %r15d
xorl %r14d, %r14d
cmpq %r14, %r15
je 0x2c50f
movq 0x20(%rbx), %r13
movq 0x28(%rbx), %rax
andl $0x0, (%rax,%r14,4)
leaq (%r12,%r13), %rbp
leaq (%r12,%r13), %rdi
addq $0x18, %rdi
movq %rbx, -0x18(%rdi)
movl %r14d, -0x10(%rdi)
xorl %esi, %esi
callq 0x45d0
leaq (%r12,%r13), %rdi
addq $0x10, %rdi
leaq 0x20(%rsp), %rsi
leaq 0xfb(%rip), %rdx        # 0x2c524
movq %rbp, %rcx
callq 0x4920
testl %eax, %eax
jne 0x2c441
incq %r14
addq $0x48, %r12
jmp 0x2c3e4
xorl %r14d, %r14d
callq 0x4050
movq %rax, %r15
movl (%rax), %r12d
movl %r12d, %edi
callq 0x4150
leaq 0x4e991(%rip), %rsi     # 0x7adec
leaq 0x4e999(%rip), %rdx     # 0x7adfb
xorl %r13d, %r13d
pushq $0x1
popq %rdi
movq %rax, %rcx
xorl %eax, %eax
callq 0x110c6
movl $0x1, 0x8(%rbx)
movq (%rsp), %rdi
callq 0x4340
imulq $0x48, %r14, %r14
cmpq %r13, %r14
je 0x2c4b2
movq 0x20(%rbx), %rax
movq 0x10(%rax,%r13), %rdi
xorl %esi, %esi
callq 0x4410
movq 0x20(%rbx), %rax
leaq (%rax,%r13), %rdi
addq $0x18, %rdi
callq 0x49a0
addq $0x48, %r13
jmp 0x2c486
movq (%rsp), %rdi
callq 0x4590
cmpl $0x0, 0xc(%rsp)
js 0x2c4cc
leaq 0x20(%rsp), %rdi
callq 0x4870
movq 0x28(%rbx), %rdi
callq 0x45c0
movq 0x20(%rbx), %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x45c0
movl %r12d, (%r15)
jmp 0x2c4fb
movq %r14, %rdi
callq 0x45c0
movq %rbx, %rdi
callq 0x45c0
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rsp), %rdi
callq 0x4340
leaq 0x20(%rsp), %rdi
callq 0x4870
jmp 0x2c4fd