// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/cram/cram_io.c
// Function: cram_close
int cram_close(cram_fd *fd) {
    spare_bams *bl, *next;
    int i, ret = 0;

    if (!fd)
        return -1;

    if (fd->mode == 'w' && fd->ctr) {
        if(fd->ctr->slice)
            cram_update_curr_slice(fd->ctr, fd->version);

        if (-1 == cram_flush_container_mt(fd, fd->ctr))
            ret = -1;
    }

    if (fd->mode != 'w')
        cram_drain_rqueue(fd);

    if (fd->pool && fd->eof >= 0 && fd->rqueue) {
        hts_tpool_process_flush(fd->rqueue);

        if (0 != cram_flush_result(fd))
            ret = -1;

        if (fd->mode == 'w')
            fd->ctr = NULL; // prevent double freeing

        //fprintf(stderr, "CRAM: destroy queue %p\n", fd->rqueue);

        hts_tpool_process_destroy(fd->rqueue);
    }

    pthread_mutex_destroy(&fd->metrics_lock);
    pthread_mutex_destroy(&fd->ref_lock);
    pthread_mutex_destroy(&fd->range_lock);
    pthread_mutex_destroy(&fd->bam_list_lock);

    if (ret == 0 && fd->mode == 'w') {
        /* Write EOF block */
        if (0 != cram_write_eof_block(fd))
            ret = -1;
    }

    for (bl = fd->bl; bl; bl = next) {
        int max_rec = fd->seqs_per_slice * fd->slices_per_container;

        next = bl->next;
        free_bam_list(bl->bams, max_rec);
        free(bl);
    }

    if (hclose(fd->fp) != 0)
        ret = -1;

    if (fd->file_def)
        cram_free_file_def(fd->file_def);

    if (fd->header)
        sam_hdr_destroy(fd->header);

    free(fd->prefix);

    if (fd->ctr)
        cram_free_container(fd->ctr);

    if (fd->ctr_mt && fd->ctr_mt != fd->ctr)
        cram_free_container(fd->ctr_mt);

    if (fd->refs)
        refs_free(fd->refs);
    if (fd->ref_free)
        free(fd->ref_free);

    for (i = 0; i < DS_END; i++)
        if (fd->m[i])
            free(fd->m[i]);

    if (fd->tags_used) {
        khint_t k;

        for (k = kh_begin(fd->tags_used); k != kh_end(fd->tags_used); k++) {
            if (kh_exist(fd->tags_used, k))
                free(kh_val(fd->tags_used, k));
        }

        kh_destroy(m_metrics, fd->tags_used);
    }

    if (fd->index)
        cram_index_free(fd);

    if (fd->own_pool && fd->pool)
        hts_tpool_destroy(fd->pool);

    if (fd->idxfp)
        if (bgzf_close(fd->idxfp) < 0)
            ret = -1;

    free(fd);

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
testq %rdi, %rdi
je 0x44fc9
movq %rdi, %rbx
xorl %ebp, %ebp
cmpl $0x77, 0x8(%rdi)
jne 0x44fbf
movq 0x38(%rbx), %rsi
testq %rsi, %rsi
je 0x44fd1
cmpq $0x0, 0x90(%rsi)
je 0x44fa6
movl 0xc(%rbx), %eax
movq %rsi, %rdi
movl %eax, %esi
callq 0x3afd5
movq 0x38(%rbx), %rsi
movq %rbx, %rdi
callq 0x432eb
xorl %ebp, %ebp
cmpl $-0x1, %eax
sete %bpl
negl %ebp
cmpl $0x77, 0x8(%rbx)
je 0x44fd3
movq %rbx, %rdi
callq 0x33459
jmp 0x44fd3
pushq $-0x1
popq %rbp
jmp 0x451e5
xorl %ebp, %ebp
cmpq $0x0, 0x88b8(%rbx)
je 0x4501e
cmpl $0x0, 0x8890(%rbx)
js 0x4501e
movq 0x88c0(%rbx), %rdi
testq %rdi, %rdi
je 0x4501e
callq 0x2cb1f
movq %rbx, %rdi
callq 0x43440
xorl %ecx, %ecx
negl %eax
sbbl %ecx, %ecx
cmpl $0x77, 0x8(%rbx)
jne 0x45010
andq $0x0, 0x38(%rbx)
orl %ecx, %ebp
movq 0x88c0(%rbx), %rdi
callq 0x2bd67
leaq 0x88c8(%rbx), %rdi
callq 0x4590
leaq 0x88f0(%rbx), %rdi
callq 0x4590
leaq 0x8918(%rbx), %rdi
callq 0x4590
leaq 0x8948(%rbx), %rdi
callq 0x4590
testl %ebp, %ebp
je 0x45058
pushq $-0x1
popq %r15
jmp 0x45071
xorl %r15d, %r15d
cmpl $0x77, 0x8(%rbx)
jne 0x45071
movq %rbx, %rdi
callq 0x44e67
xorl %r15d, %r15d
negl %eax
sbbl %r15d, %r15d
movq 0x8940(%rbx), %r14
testq %r14, %r14
je 0x450a3
movl 0x21c(%rbx), %esi
imull 0x214(%rbx), %esi
movq (%r14), %rdi
movq 0x8(%r14), %r12
callq 0x4277f
movq %r14, %rdi
callq 0x45c0
movq %r12, %r14
jmp 0x45078
movq (%rbx), %rdi
callq 0xd8ee
xorl %ebp, %ebp
negl %eax
sbbl %ebp, %ebp
movq 0x10(%rbx), %rdi
callq 0x45c0
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x450c8
callq 0x1d61e
movq 0x20(%rbx), %rdi
callq 0x45c0
movq 0x38(%rbx), %rdi
testq %rdi, %rdi
je 0x450df
callq 0x4237d
movq 0x40(%rbx), %rdi
testq %rdi, %rdi
je 0x450f3
cmpq 0x38(%rbx), %rdi
je 0x450f3
callq 0x4237d
movq 0x50(%rbx), %rdi
testq %rdi, %rdi
je 0x45101
callq 0x407fe
orl %r15d, %ebp
movq 0x60(%rbx), %rdi
callq 0x45c0
pushq $0x12
popq %r14
cmpq $0x41, %r14
je 0x45125
movq (%rbx,%r14,8), %rdi
callq 0x45c0
incq %r14
jmp 0x45111
movq 0x208(%rbx), %r14
testq %r14, %r14
je 0x45198
xorl %r15d, %r15d
xorl %r12d, %r12d
cmpl (%r14), %r12d
je 0x45175
movq 0x10(%r14), %rax
movl %r12d, %ecx
shrl $0x4, %ecx
movl (%rax,%rcx,4), %eax
movl %r15d, %ecx
andb $0x1e, %cl
shrl %cl, %eax
testb $0x3, %al
jne 0x4516c
movq 0x20(%r14), %rax
movl %r12d, %ecx
movq (%rax,%rcx,8), %rdi
callq 0x45c0
movq 0x208(%rbx), %r14
incl %r12d
addl $0x2, %r15d
jmp 0x45137
movq 0x18(%r14), %rdi
callq 0x45c0
movq 0x10(%r14), %rdi
callq 0x45c0
movq 0x20(%r14), %rdi
callq 0x45c0
movq %r14, %rdi
callq 0x45c0
cmpq $0x0, 0x8878(%rbx)
je 0x451aa
movq %rbx, %rdi
callq 0x3d574
cmpl $0x0, 0x88b0(%rbx)
je 0x451c4
movq 0x88b8(%rbx), %rdi
testq %rdi, %rdi
je 0x451c4
callq 0x2cc8f
movq 0x8988(%rbx), %rdi
testq %rdi, %rdi
je 0x451dd
callq 0xbc96
testl %eax, %eax
pushq $-0x1
popq %rax
cmovsl %eax, %ebp
movq %rbx, %rdi
callq 0x45c0
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq