// File: /workspace/github_c_makefile_star2_O3/johsteffens[P]beth/lib/bcore/bcore_tbman.c
// Function: tbman_alloc_challenge
static st_s* tbman_alloc_challenge
(
    fp_alloc alloc,
    uz_t table_size,
    uz_t cycles,
    uz_t max_alloc,
    u2_t seed,
    bl_t cleanup,
    bl_t verbose
)
{
    st_s* str = st_s_create();

    vd_t* data_table = malloc( table_size * sizeof( vd_t ) );
    uz_t* size_table = malloc( table_size * sizeof( uz_t ) );
    for( uz_t i = 0; i < table_size; i++ ) data_table[ i ] = NULL;
    for( uz_t i = 0; i < table_size; i++ ) size_table[ i ] = 0;

    u2_t rval = seed;
    uz_t alloc_attempts = 0;
    uz_t realloc_attempts = 0;
    uz_t free_attempts = 0;
    uz_t alloc_failures = 0;
    uz_t realloc_failures = 0;
    uz_t free_failures = 0;

    for( uz_t j = 0; j < cycles; j++ )
    {
        for( uz_t i = 0; i < table_size; i++ )
        {
            rval = bcore_xsg_u2( rval );
            uz_t idx = rval % table_size;

            // verify table content
            if( size_table[ idx ] > 0 )
            {
                u2_t rv = bcore_xsg_u2( idx + 1 );
                uint8_t* data = data_table[ idx ];
                uz_t sz = size_table[ idx ];
                for( uz_t i = 0; i < sz; i++ )
                {
                    rv = bcore_xsg_u2( rv );
                    if( data[ i ] != ( rv & 255 ) )
                    {
                        ERR( "data failure [%u vs %u].", ( u2_t )data[ i ], ( u2_t )( rv & 255 ) );
                    }
                }
            }

            if( data_table[ idx ] == NULL )
            {
                rval = bcore_xsg_u2( rval );
                uz_t size = pow( ( double )max_alloc, ( rval * pow( 2.0, -32 ) ) );
                data_table[ idx ] = alloc( data_table[ idx ], 0, size, &size_table[ idx ] );
                alloc_attempts++;
                alloc_failures += ( size > 0 ) && ( data_table[ idx ] == NULL );

                // set new content
                if( size_table[ idx ] > 0 )
                {
                    u2_t rv = bcore_xsg_u2( idx + 1 );
                    uint8_t* data = data_table[ idx ];
                    uz_t sz = size_table[ idx ];
                    for( uz_t i = 0; i < sz; i++ ) data[ i ] = ( ( rv = bcore_xsg_u2( rv ) ) & 255 );
                }
            }
            else
            {
                rval = bcore_xsg_u2( rval );
                if( rval & 32 )
                {
                    data_table[ idx ] = alloc( data_table[ idx ], size_table[ idx ], 0, &size_table[ idx ] ); // free
                    free_attempts++;
                    free_failures += ( data_table[ idx ] != NULL );
                }
                else
                {
                    rval = bcore_xsg_u2( rval );
                    uz_t size = pow( ( double )max_alloc, rval * pow( 2.0, -32 ) );

                    uz_t new_size = 0;

                    data_table[ idx ] = alloc( data_table[ idx ], size_table[ idx ], size, &new_size ); // realloc

                    // verify old table content (only when size > sz - stdlib realloc does not seem to retain data otherwise)
                    if( size > size_table[ idx ] )
                    {
                        if( data_table[ idx ] != NULL && size_table[ idx ] > 0 )
                        {
                            u2_t rv = bcore_xsg_u2( idx + 1 );
                            uint8_t* data = data_table[ idx ];
                            uz_t sz = size_table[ idx ];
                            for( uz_t i = 0; i < sz; i++ )
                            {
                                rv = bcore_xsg_u2( rv );
                                if( data[ i ] != ( rv & 255 ) )
                                {
                                    ERR( "data failure [%u vs %u].", ( u2_t )data[ i ], ( u2_t )( rv & 255 ) );
                                }
                            }
                        }
                    }

                    size_table[ idx ] = new_size; //( data_table[ idx ] != NULL ) ? size : 0;
                    realloc_attempts++;
                    realloc_failures += ( size > 0 ) && ( data_table[ idx ] == NULL );

                    // set new content
                    if( size_table[ idx ] > 0 )
                    {
                        u2_t rv = bcore_xsg_u2( idx + 1 );
                        uint8_t* data = data_table[ idx ];
                        uz_t sz = size_table[ idx ];
                        for( uz_t i = 0; i < sz; i++ ) data[ i ] = ( ( rv = bcore_xsg_u2( rv ) ) & 255 );
                    }
                }
            }
        }
    }

    uz_t allocated_table_size = 0;
    for( uz_t i = 0; i < table_size; i++ ) allocated_table_size += ( data_table[ i ] != NULL );

    if( verbose )
    {
        st_s_pushf( str, "cycles ............... %zu\n", cycles );
        st_s_pushf( str, "max alloc ............ %zu\n", max_alloc );
        st_s_pushf( str, "Instances\n" );
        st_s_pushf( str, "  total .............. %zu\n", table_size );
        st_s_pushf( str, "  allocated .......... %zu\n", allocated_table_size );
        st_s_pushf( str, "Alloc\n" );
        st_s_pushf( str, "  attempts  .......... %zu\n", alloc_attempts );
        st_s_pushf( str, "  failures  .......... %zu\n", alloc_failures );
        st_s_pushf( str, "Realloc\n" );
        st_s_pushf( str, "  attempts  .......... %zu\n", realloc_attempts );
        st_s_pushf( str, "  failures  .......... %zu\n", realloc_failures );
        st_s_pushf( str, "Free\n" );
        st_s_pushf( str, "  attempts  .......... %zu\n", free_attempts );
        st_s_pushf( str, "  failures  .......... %zu\n", free_failures );
    }

    // speed test
    {
        clock_t time = clock();
        for( uz_t j = 0; j < cycles; j++ )
        {
            for( uz_t i = 0; i < table_size; i++ )
            {
                rval = bcore_xsg_u2( rval );
                uz_t idx = rval % table_size;
                if( data_table[ idx ] == NULL )
                {
                    uz_t size = pow( ( double )max_alloc, rval * pow( 2.0, -32 ) );
                    data_table[ idx ] = alloc( data_table[ idx ], 0, size, &size_table[ idx ] );
                }
                else
                {
                    data_table[ idx ] = alloc( data_table[ idx ], size_table[ idx ], 0, &size_table[ idx ] ); // free
                }
            }
        }
        time = clock() - time;
        st_s_pushf( str, "speed test alloc-free: %5.3gs\n", ( double )time / ( CLOCKS_PER_SEC  * cycles  * table_size ) );
    }
    // speed test
    {
        clock_t time = clock();
        for( uz_t j = 0; j < cycles; j++ )
        {
            for( uz_t i = 0; i < table_size; i++ )
            {
                rval = bcore_xsg_u2( rval );
                uz_t idx = rval % table_size;
                rval = bcore_xsg_u2( rval );
                uz_t size = pow( ( double )max_alloc, rval * pow( 2.0, -32 ) );
                data_table[ idx ] = alloc( data_table[ idx ], size_table[ idx ], size, &size_table[ idx ] ); // realloc
            }
        }
        time = clock() - time;
        st_s_pushf( str, "speed test realloc:    %5.3gs\n", ( double )time / ( CLOCKS_PER_SEC  * cycles  * table_size ) );
    }

    // cleanup
    if( cleanup ) for( uz_t i = 0; i < table_size; i++ ) data_table[ i ] = alloc( data_table[ i ], size_table[ i ], 0, NULL );

    free( size_table );
    free( data_table );
    return str;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, %ebx
movq %rcx, 0x48(%rsp)
movq %rdx, 0x18(%rsp)
movq %rsi, %rbp
movq %rdi, 0x8(%rsp)
xorl %eax, %eax
callq 0x109c82
movq %rax, %r15
leaq (,%rbp,8), %r14
movq %r14, %rdi
callq 0xd160
movq %rax, %r12
movq %r14, %rdi
callq 0xd160
movq %rax, %r13
testq %rbp, %rbp
je 0x11215d
movq %r12, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xd090
movq %r13, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xd090
movq %r13, 0x28(%rsp)
movq %r12, (%rsp)
cmpq $0x0, 0x18(%rsp)
movq %rbp, 0x30(%rsp)
movq %r15, 0x50(%rsp)
je 0x112582
cvtsi2sdq 0x48(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
xorl %eax, %eax
movq (%rsp), %rsi
movq %rax, 0x60(%rsp)
testq %rbp, %rbp
je 0x1124a7
xorl %eax, %eax
movq %rax, 0x10(%rsp)
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
movq %rbx, %rax
xorl %edx, %edx
divq %rbp
movq %rdx, %r13
movq 0x28(%rsp), %rax
leaq (%rax,%rdx,8), %r15
movq (%rax,%rdx,8), %r14
testq %r14, %r14
movq %r15, 0x38(%rsp)
je 0x112265
leaq (%rsi,%r13,8), %rax
movq %rax, 0x40(%rsp)
leal 0x1(%r13), %eax
movl %eax, %ecx
shrl $0x7, %ecx
xorl %eax, %ecx
movl %ecx, %eax
shll $0x19, %eax
xorl %ecx, %eax
movl %eax, %ebp
shrl $0xc, %ebp
xorl %eax, %ebp
movq (%rsi,%r13,8), %r12
xorl %r15d, %r15d
movl %ebp, %eax
shrl $0x7, %eax
xorl %ebp, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebp
shrl $0xc, %ebp
xorl %ecx, %ebp
movzbl (%r12,%r15), %r8d
movzbl %bpl, %r9d
cmpl %r8d, %r9d
je 0x11224c
leaq 0x3b51f(%rip), %rdi     # 0x14d751
leaq 0x3aab4(%rip), %rsi     # 0x14cced
movl $0xae9, %edx            # imm = 0xAE9
leaq 0x3b522(%rip), %rcx     # 0x14d767
xorl %eax, %eax
callq 0xbe592
incq %r15
cmpq %r15, %r14
jne 0x112208
movq 0x30(%rsp), %rbp
movq 0x38(%rsp), %r15
movq 0x40(%rsp), %r14
jmp 0x112276
leaq (%rsi,%r13,8), %r14
movq (%rsi,%r13,8), %r12
testq %r12, %r12
je 0x1123fc
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
testb $0x20, %bl
jne 0x1123d0
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
cvtsi2sd %rbx, %xmm1
mulsd 0x3a9da(%rip), %xmm1    # 0x14cc90
movsd 0x20(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x24fa3(%rip), %xmm0    # 0x137278
cvttsd2si %xmm0, %rbp
andq %rcx, %rbp
orq %rax, %rbp
movq $0x0, 0x58(%rsp)
movq (%r15), %rsi
movq %r12, %rdi
movq %rbp, %rdx
leaq 0x58(%rsp), %rcx
callq *0x8(%rsp)
movq %rax, %r12
movq %rax, (%r14)
movq (%r15), %r14
testq %r14, %r14
je 0x11237b
cmpq %rbp, %r14
jae 0x11237b
testq %r12, %r12
je 0x11237b
leal 0x1(%r13), %eax
movl %eax, %ecx
shrl $0x7, %ecx
xorl %eax, %ecx
movl %ecx, %eax
shll $0x19, %eax
xorl %ecx, %eax
movl %eax, %ebp
shrl $0xc, %ebp
xorl %eax, %ebp
xorl %r15d, %r15d
movl %ebp, %eax
shrl $0x7, %eax
xorl %ebp, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebp
shrl $0xc, %ebp
xorl %ecx, %ebp
movzbl (%r12,%r15), %r8d
movzbl %bpl, %r9d
cmpl %r8d, %r9d
je 0x112373
leaq 0x3b3f8(%rip), %rdi     # 0x14d751
leaq 0x3a98d(%rip), %rsi     # 0x14cced
movl $0xb1e, %edx            # imm = 0xB1E
leaq 0x3b3fb(%rip), %rcx     # 0x14d767
xorl %eax, %eax
callq 0xbe592
incq %r15
cmpq %r15, %r14
jne 0x11232f
movq 0x58(%rsp), %rax
movq 0x38(%rsp), %rcx
movq %rax, (%rcx)
testq %rax, %rax
movq 0x30(%rsp), %rbp
je 0x1123e2
leal 0x1(%r13), %ecx
movl %ecx, %edx
shrl $0x7, %edx
xorl %ecx, %edx
movl %edx, %ecx
shll $0x19, %ecx
xorl %edx, %ecx
movl %ecx, %edx
shrl $0xc, %edx
xorl %ecx, %edx
xorl %ecx, %ecx
movl %edx, %esi
shrl $0x7, %esi
xorl %edx, %esi
movl %esi, %edi
shll $0x19, %edi
xorl %esi, %edi
movl %edi, %edx
shrl $0xc, %edx
xorl %edi, %edx
movb %dl, (%r12,%rcx)
incq %rcx
cmpq %rcx, %rax
jne 0x1123ad
jmp 0x1123e2
movq (%r15), %rsi
movq %r12, %rdi
xorl %edx, %edx
movq %r15, %rcx
callq *0x8(%rsp)
movq %rax, (%r14)
movq (%rsp), %rsi
movq 0x10(%rsp), %rax
incq %rax
cmpq %rbp, %rax
jne 0x11219f
jmp 0x1124a7
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
xorps %xmm1, %xmm1
cvtsi2sd %rbx, %xmm1
mulsd 0x3a86f(%rip), %xmm1    # 0x14cc90
movsd 0x20(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x24e38(%rip), %xmm0    # 0x137278
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
xorl %edi, %edi
xorl %esi, %esi
movq %r15, %rcx
callq *0x8(%rsp)
movq %rax, (%r14)
movq (%r15), %rcx
testq %rcx, %rcx
je 0x1123e2
leal 0x1(%r13), %edx
movl %edx, %esi
shrl $0x7, %esi
xorl %edx, %esi
movl %esi, %edx
shll $0x19, %edx
xorl %esi, %edx
movl %edx, %esi
shrl $0xc, %esi
xorl %edx, %esi
xorl %edx, %edx
movl %esi, %edi
shrl $0x7, %edi
xorl %esi, %edi
movl %edi, %r8d
shll $0x19, %r8d
xorl %edi, %r8d
movl %r8d, %esi
shrl $0xc, %esi
xorl %r8d, %esi
movb %sil, (%rax,%rdx)
incq %rdx
cmpq %rdx, %rcx
jne 0x11247c
jmp 0x1123e2
movq 0x60(%rsp), %rax
incq %rax
cmpq 0x18(%rsp), %rax
jne 0x11218f
callq 0xd340
movq (%rsp), %rsi
movq %rax, %r14
xorl %r12d, %r12d
movq %rbp, %r13
testq %rbp, %rbp
je 0x11256d
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
movq %rbx, %rax
xorl %edx, %edx
divq %rbp
movq %rdx, %r15
movq (%rsi,%rdx,8), %rdi
testq %rdi, %rdi
je 0x11250f
movq 0x28(%rsp), %rax
leaq (%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rsi
xorl %edx, %edx
jmp 0x112558
movl %ebx, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
mulsd 0x3a76f(%rip), %xmm1    # 0x14cc90
movsd 0x20(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x24d3c(%rip), %xmm0    # 0x137278
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq 0x28(%rsp), %rax
leaq (%rax,%r15,8), %rcx
xorl %edi, %edi
xorl %esi, %esi
callq *0x8(%rsp)
movq (%rsp), %rsi
movq %rax, (%rsi,%r15,8)
decq %r13
jne 0x1124d5
incq %r12
cmpq 0x18(%rsp), %r12
jne 0x1124c9
movq 0x50(%rsp), %r15
jmp 0x11258a
callq 0xd340
movq %rax, %r14
callq 0xd340
subq %r14, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movq 0x18(%rsp), %r14
imulq %r14, %rbp
imulq $0xf4240, %rbp, %rax    # imm = 0xF4240
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
movsd %xmm1, 0x40(%rsp)
divsd %xmm1, %xmm0
leaq 0x3b1bd(%rip), %rsi     # 0x14d780
movq %r15, %rdi
movb $0x1, %al
callq 0x10a7d0
callq 0xd340
movq %rax, 0x20(%rsp)
testq %r14, %r14
je 0x1126bc
xorps %xmm0, %xmm0
cvtsi2sdq 0x48(%rsp), %xmm0
xorl %eax, %eax
movsd 0x3a69c(%rip), %xmm2    # 0x14cc90
movsd %xmm0, 0x38(%rsp)
movq 0x30(%rsp), %rbp
movq (%rsp), %r12
movq 0x28(%rsp), %r14
movq %rax, 0x10(%rsp)
movq %rbp, %r13
testq %rbp, %rbp
je 0x1126a9
movl %ebx, %eax
shrl $0x7, %eax
xorl %ebx, %eax
movl %eax, %edx
shll $0x19, %edx
xorl %eax, %edx
movl %edx, %ecx
shrl $0xc, %ecx
xorl %edx, %ecx
movq %rcx, %rax
xorl %edx, %edx
divq %rbp
movq %rdx, %r15
movl %ecx, %eax
shrl $0x7, %eax
xorl %ecx, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %ebx
shrl $0xc, %ebx
xorl %ecx, %ebx
xorps %xmm1, %xmm1
cvtsi2sd %rbx, %xmm1
mulsd %xmm2, %xmm1
movsd 0x38(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x24bff(%rip), %xmm0    # 0x137278
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq (%r12,%r15,8), %rdi
leaq (%r14,%r15,8), %rcx
movq (%r14,%r15,8), %rsi
callq *0x8(%rsp)
movsd 0x3a5f4(%rip), %xmm2    # 0x14cc90
movq %rax, (%r12,%r15,8)
decq %r13
jne 0x112619
movq 0x10(%rsp), %rax
incq %rax
cmpq 0x18(%rsp), %rax
jne 0x112608
callq 0xd340
subq 0x20(%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x40(%rsp), %xmm0
leaq 0x3b0c4(%rip), %rsi     # 0x14d79f
movq 0x50(%rsp), %r14
movq %r14, %rdi
movb $0x1, %al
callq 0x10a7d0
movq 0x30(%rsp), %r15
testq %r15, %r15
movq 0x8(%rsp), %r12
movq (%rsp), %rcx
movq 0x28(%rsp), %r13
je 0x112724
xorl %ebx, %ebx
movq (%rcx,%rbx,8), %rdi
movq (%r13,%rbx,8), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *%r12
movq (%rsp), %rcx
movq %rax, (%rcx,%rbx,8)
incq %rbx
cmpq %rbx, %r15
jne 0x112704
movq %r13, %rdi
movq %rcx, %rbx
callq 0xd220
movq %rbx, %rdi
callq 0xd220
movq %r14, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq