// File: /workspace/github_c_makefile_star2_O3/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 0x5323c
movq %rdi, %rbx
xorl %ebp, %ebp
cmpl $0x77, 0x8(%rdi)
jne 0x53232
movq 0x38(%rbx), %rsi
testq %rsi, %rsi
je 0x53246
cmpq $0x0, 0x90(%rsi)
je 0x53219
movl 0xc(%rbx), %eax
movq %rsi, %rdi
movl %eax, %esi
callq 0x47686
movq 0x38(%rbx), %rsi
movq %rbx, %rdi
callq 0x51009
xorl %ebp, %ebp
cmpl $-0x1, %eax
sete %bpl
negl %ebp
cmpl $0x77, 0x8(%rbx)
je 0x53248
movq %rbx, %rdi
callq 0x3e1ed
jmp 0x53248
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x5347a
xorl %ebp, %ebp
cmpq $0x0, 0x88b8(%rbx)
je 0x53296
cmpl $0x0, 0x8890(%rbx)
js 0x53296
movq 0x88c0(%rbx), %rdi
testq %rdi, %rdi
je 0x53296
callq 0x36d84
movq %rbx, %rdi
callq 0x511ab
xorl %ecx, %ecx
negl %eax
sbbl %ecx, %ecx
cmpl $0x77, 0x8(%rbx)
jne 0x53288
movq $0x0, 0x38(%rbx)
orl %ecx, %ebp
movq 0x88c0(%rbx), %rdi
callq 0x35f44
leaq 0x88c8(%rbx), %rdi
callq 0x4590
leaq 0x88f0(%rbx), %rdi
callq 0x4590
leaq 0x8918(%rbx), %rdi
callq 0x4590
leaq 0x8948(%rbx), %rdi
callq 0x4590
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
testl %ebp, %ebp
jne 0x532e9
xorl %r15d, %r15d
cmpl $0x77, 0x8(%rbx)
jne 0x532e9
movq %rbx, %rdi
callq 0x530b1
xorl %r15d, %r15d
negl %eax
sbbl %r15d, %r15d
movq 0x8940(%rbx), %r14
testq %r14, %r14
je 0x5331e
movl 0x21c(%rbx), %esi
imull 0x214(%rbx), %esi
movq (%r14), %rdi
movq 0x8(%r14), %r12
callq 0x502fe
movq %r14, %rdi
callq 0x45c0
movq %r12, %r14
testq %r12, %r12
jne 0x532f5
movq (%rbx), %rdi
callq 0xf4df
xorl %ebp, %ebp
negl %eax
sbbl %ebp, %ebp
movq 0x10(%rbx), %rdi
testq %rdi, %rdi
je 0x5333a
callq 0x45c0
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x53348
callq 0x22102
movq 0x20(%rbx), %rdi
callq 0x45c0
movq 0x38(%rbx), %rdi
testq %rdi, %rdi
je 0x5335f
callq 0x4fe2e
movq 0x40(%rbx), %rdi
testq %rdi, %rdi
je 0x53373
cmpq 0x38(%rbx), %rdi
je 0x53373
callq 0x4fe2e
movq 0x50(%rbx), %rdi
testq %rdi, %rdi
je 0x53381
callq 0x4de72
movq 0x60(%rbx), %rdi
testq %rdi, %rdi
je 0x5338f
callq 0x45c0
orl %r15d, %ebp
movl $0x12, %r14d
movq (%rbx,%r14,8), %rdi
testq %rdi, %rdi
je 0x533a6
callq 0x45c0
incq %r14
cmpq $0x41, %r14
jne 0x53398
movq 0x208(%rbx), %r14
testq %r14, %r14
je 0x5342b
movl (%r14), %eax
testl %eax, %eax
je 0x53408
xorl %r15d, %r15d
xorl %r12d, %r12d
movq 0x10(%r14), %rcx
movl %r12d, %edx
shrl $0x4, %edx
movl (%rcx,%rdx,4), %edx
movl %r15d, %ecx
andb $0x1e, %cl
shrl %cl, %edx
testb $0x3, %dl
jne 0x533fc
movq 0x20(%r14), %rax
movl %r12d, %ecx
movq (%rax,%rcx,8), %rdi
callq 0x45c0
movq 0x208(%rbx), %r14
movl (%r14), %eax
incl %r12d
addl $0x2, %r15d
cmpl %eax, %r12d
jne 0x533c8
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 0x5343d
movq %rbx, %rdi
callq 0x49d49
cmpl $0x0, 0x88b0(%rbx)
je 0x53457
movq 0x88b8(%rbx), %rdi
testq %rdi, %rdi
je 0x53457
callq 0x36efb
movq 0x8988(%rbx), %rdi
testq %rdi, %rdi
je 0x53472
callq 0xd3cd
testl %eax, %eax
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmovsl %eax, %ebp
movq %rbx, %rdi
callq 0x45c0
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq