// File: karel-brinda[P]ococo/ext/htslib/bgzf.c
// Function: bgzf_mt
int bgzf_mt(BGZF *fp, int n_threads, int n_sub_blks)
{
    int i;
    mtaux_t *mt;
    pthread_attr_t attr;
    if (!fp->is_write || fp->mt || n_threads <= 1) return -1;
    mt = (mtaux_t*)calloc(1, sizeof(mtaux_t));
    mt->n_threads = n_threads;
    mt->n_blks = n_threads * n_sub_blks;
    mt->len = (int*)calloc(mt->n_blks, sizeof(int));
    mt->blk = (void**)calloc(mt->n_blks, sizeof(void*));
    for (i = 0; i < mt->n_blks; ++i)
        mt->blk[i] = malloc(BGZF_MAX_BLOCK_SIZE);
    mt->tid = (pthread_t*)calloc(mt->n_threads, sizeof(pthread_t)); // tid[0] is not used, as the worker 0 is launched by the master
    mt->w = (worker_t*)calloc(mt->n_threads, sizeof(worker_t));
    for (i = 0; i < mt->n_threads; ++i) {
        mt->w[i].i = i;
        mt->w[i].mt = mt;
        mt->w[i].compress_level = fp->compress_level;
        mt->w[i].buf = malloc(BGZF_MAX_BLOCK_SIZE);
    }
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_mutex_init(&mt->lock, 0);
    pthread_cond_init(&mt->cv, 0);
    for (i = 1; i < mt->n_threads; ++i) // worker 0 is effectively launched by the master thread
        pthread_create(&mt->tid[i], &attr, mt_worker, &mt->w[i]);
    fp->mt = mt;
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
shrl $0x10, %eax
andl $0x3, %eax
cmpl $0x0, %eax
je 0x64e24
movq -0x10(%rbp), %rax
cmpq $0x0, 0x40(%rax)
jne 0x64e24
cmpl $0x1, -0x14(%rbp)
jg 0x64e30
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x65040
movl $0x1, %edi
movl $0x90, %esi
callq 0x4370
movq %rax, -0x28(%rbp)
movl -0x14(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movl -0x14(%rbp), %ecx
imull -0x18(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x28(%rbp), %rax
movslq 0x4(%rax), %rdi
movl $0x4, %esi
callq 0x4370
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movslq 0x4(%rax), %rdi
movl $0x8, %esi
callq 0x4370
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x18(%rax)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x64ecf
movl $0x10000, %edi          # imm = 0x10000
callq 0x47a0
movq %rax, %rdx
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x1c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x64e9b
movq -0x28(%rbp), %rax
movslq (%rax), %rdi
movl $0x8, %esi
callq 0x4370
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x28(%rbp), %rax
movslq (%rax), %rdi
movl $0x20, %esi
callq 0x4370
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x28(%rax)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x64fa4
movl -0x1c(%rbp), %ecx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x1c(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movl %ecx, 0x10(%rax)
movq -0x28(%rbp), %rcx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x1c(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %ecx
shll $0x3, %ecx
sarl $0x17, %ecx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x1c(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movl %ecx, 0x1c(%rax)
movl $0x10000, %edi          # imm = 0x10000
callq 0x47a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movslq -0x1c(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x64f0e
leaq -0x60(%rbp), %rdi
callq 0x46d0
leaq -0x60(%rbp), %rdi
xorl %esi, %esi
callq 0x4790
movq -0x28(%rbp), %rdi
addq $0x38, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x48a0
movq -0x28(%rbp), %rdi
addq $0x60, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x46b0
movl $0x1, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x6502d
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rdi
movslq -0x1c(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rcx
movslq -0x1c(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rcx
leaq -0x60(%rbp), %rsi
leaq 0x33(%rip), %rdx        # 0x65050
callq 0x4a90
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x64fe1
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x40(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)