// File: /workspace/github_c_makefile_star2_O1/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, 0x40(%rsp)
movq %rdx, 0x28(%rsp)
movq %rsi, %r12
movq %rdi, 0x18(%rsp)
xorl %eax, %eax
callq 0x114bbb
movq %rax, %r15
leaq (,%r12,8), %r14
movq %r14, %rdi
callq 0xd160
movq %rax, %r13
movq %r14, %rdi
callq 0xd160
movq %rax, %rbp
movq %r12, 0x20(%rsp)
testq %r12, %r12
movq %r13, %r12
je 0x11d3bd
movq %r12, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xd090
movq %rbp, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xd090
movq %rbp, 0x10(%rsp)
cmpq $0x0, 0x28(%rsp)
movq %r12, 0x30(%rsp)
movq %r15, 0x58(%rsp)
je 0x11d711
cvtsi2sdq 0x40(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
xorl %eax, %eax
movq 0x20(%rsp), %r15
movq 0x10(%rsp), %r14
movq %rax, 0x48(%rsp)
testq %r15, %r15
je 0x11d6fc
xorl %eax, %eax
movq %rax, 0x8(%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 %r15
movq %rdx, %r13
movq (%r14,%rdx,8), %r15
testq %r15, %r15
je 0x11d4a0
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 0x30(%rsp), %rax
movq (%rax,%r13,8), %r12
xorl %r14d, %r14d
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,%r14), %r8d
movzbl %bpl, %r9d
cmpl %r8d, %r9d
je 0x11d498
leaq 0x3b27b(%rip), %rdi     # 0x1586f9
leaq 0x3a810(%rip), %rsi     # 0x157c95
movl $0xae9, %edx            # imm = 0xAE9
leaq 0x3b27e(%rip), %rcx     # 0x15870f
xorl %eax, %eax
callq 0xc80f6
incq %r14
cmpq %r14, %r15
jne 0x11d454
movq 0x10(%rsp), %r14
leaq (%r14,%r13,8), %r15
movq 0x30(%rsp), %r12
movq (%r12,%r13,8), %rbp
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
testq %rbp, %rbp
je 0x11d634
testb $0x20, %bl
movq 0x18(%rsp), %rax
jne 0x11d6d0
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 0x3a768(%rip), %xmm1    # 0x157c68
movsd 0x38(%rsp), %xmm0
callq 0xd460
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x24da1(%rip), %xmm0    # 0x1422c0
movq %r15, %r14
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
movq $0x0, 0x60(%rsp)
movq (%r14), %rsi
movq %rbp, %rdi
movq %r15, %rdx
leaq 0x60(%rsp), %rcx
callq *0x18(%rsp)
movq %rax, %rbp
movq %rax, (%r12,%r13,8)
movq %r14, 0x50(%rsp)
movq (%r14), %r12
testq %r12, %r12
je 0x11d5d7
cmpq %r15, %r12
jae 0x11d5d7
testq %rbp, %rbp
je 0x11d5d7
leal 0x1(%r13), %eax
movl %eax, %ecx
shrl $0x7, %ecx
xorl %eax, %ecx
movl %ecx, %eax
shll $0x19, %eax
xorl %ecx, %eax
movl %eax, %r15d
shrl $0xc, %r15d
xorl %eax, %r15d
xorl %r14d, %r14d
movl %r15d, %eax
shrl $0x7, %eax
xorl %r15d, %eax
movl %eax, %ecx
shll $0x19, %ecx
xorl %eax, %ecx
movl %ecx, %r15d
shrl $0xc, %r15d
xorl %ecx, %r15d
movzbl (%rbp,%r14), %r8d
movzbl %r15b, %r9d
cmpl %r8d, %r9d
je 0x11d5cf
leaq 0x3b144(%rip), %rdi     # 0x1586f9
leaq 0x3a6d9(%rip), %rsi     # 0x157c95
movl $0xb1e, %edx            # imm = 0xB1E
leaq 0x3b147(%rip), %rcx     # 0x15870f
xorl %eax, %eax
callq 0xc80f6
incq %r14
cmpq %r14, %r12
jne 0x11d585
movq 0x60(%rsp), %rax
movq 0x50(%rsp), %rcx
movq %rax, (%rcx)
testq %rax, %rax
movq 0x20(%rsp), %r15
je 0x11d62a
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, (%rbp,%rcx)
incq %rcx
cmpq %rcx, %rax
jne 0x11d609
movq 0x30(%rsp), %r12
jmp 0x11d6e6
movl %ebx, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
mulsd 0x3a622(%rip), %xmm1    # 0x157c68
movsd 0x38(%rsp), %xmm0
callq 0xd460
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x24c5b(%rip), %xmm0    # 0x1422c0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq %rbp, %rdi
xorl %esi, %esi
movq %r15, %rcx
callq *0x18(%rsp)
movq %rax, (%r12,%r13,8)
movq (%r15), %rcx
testq %rcx, %rcx
movq 0x20(%rsp), %r15
je 0x11d6eb
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 0x11d6a8
jmp 0x11d6eb
movq (%r15), %rsi
movq %rbp, %rdi
xorl %edx, %edx
movq %r15, %rcx
callq *%rax
movq %rax, (%r12,%r13,8)
movq 0x20(%rsp), %r15
movq 0x10(%rsp), %r14
movq 0x8(%rsp), %rax
incq %rax
cmpq %r15, %rax
jne 0x11d401
movq 0x48(%rsp), %rax
incq %rax
cmpq 0x28(%rsp), %rax
jne 0x11d3f1
jmp 0x11d716
movq 0x20(%rsp), %r15
callq 0xd340
movq %rax, %r14
cmpq $0x0, 0x28(%rsp)
je 0x11d7f9
xorps %xmm0, %xmm0
cvtsi2sdq 0x40(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
xorl %r13d, %r13d
movq %r15, %rbp
testq %r15, %r15
je 0x11d7eb
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 %r15
movq %rdx, %r15
movq (%r12,%rdx,8), %r12
testq %r12, %r12
je 0x11d786
movq 0x10(%rsp), %rax
leaq (%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rsi
movq %r12, %rdi
xorl %edx, %edx
jmp 0x11d7d0
movl %ebx, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
mulsd 0x3a4d0(%rip), %xmm1    # 0x157c68
movsd 0x8(%rsp), %xmm0
callq 0xd460
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x24b0d(%rip), %xmm0    # 0x1422c0
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq 0x10(%rsp), %rax
leaq (%rax,%r15,8), %rcx
movq %r12, %rdi
xorl %esi, %esi
callq *0x18(%rsp)
movq 0x30(%rsp), %r12
movq %rax, (%r12,%r15,8)
decq %rbp
movq 0x20(%rsp), %r15
jne 0x11d749
incq %r13
cmpq 0x28(%rsp), %r13
jne 0x11d73d
callq 0xd340
subq %r14, %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movq %r15, %rax
movq 0x28(%rsp), %r14
imulq %r14, %rax
imulq $0xf4240, %rax, %rax    # imm = 0xF4240
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
movsd %xmm1, 0x50(%rsp)
divsd %xmm1, %xmm0
leaq 0x3aef3(%rip), %rsi     # 0x158728
movq 0x58(%rsp), %rdi
movb $0x1, %al
callq 0x1156f6
callq 0xd340
movq %rax, 0x48(%rsp)
testq %r14, %r14
je 0x11d937
xorps %xmm0, %xmm0
cvtsi2sdq 0x40(%rsp), %xmm0
xorl %eax, %eax
movsd 0x3a400(%rip), %xmm2    # 0x157c68
movsd %xmm0, 0x8(%rsp)
movq 0x18(%rsp), %r14
movq 0x30(%rsp), %rbp
movq 0x10(%rsp), %r12
movq %rax, 0x38(%rsp)
movq %r15, %r13
testq %r15, %r15
je 0x11d924
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 %r15
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 0x8(%rsp), %xmm0
callq 0xd460
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x249d2(%rip), %xmm0    # 0x1422c0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq (%rbp,%r15,8), %rdi
leaq (%r12,%r15,8), %rcx
movq (%r12,%r15,8), %rsi
callq *%r14
movsd 0x3a357(%rip), %xmm2    # 0x157c68
movq %rax, (%rbp,%r15,8)
movq 0x20(%rsp), %r15
decq %r13
jne 0x11d88e
movq 0x38(%rsp), %rax
incq %rax
cmpq 0x28(%rsp), %rax
jne 0x11d87d
callq 0xd340
subq 0x48(%rsp), %rax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x50(%rsp), %xmm0
leaq 0x3adf1(%rip), %rsi     # 0x158747
movq 0x58(%rsp), %rbp
movq %rbp, %rdi
movb $0x1, %al
callq 0x1156f6
testq %r15, %r15
movq 0x18(%rsp), %r14
movq 0x30(%rsp), %r12
movq 0x10(%rsp), %r13
je 0x11d997
xorl %ebx, %ebx
movq (%r12,%rbx,8), %rdi
movq (%r13,%rbx,8), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *%r14
movq %rax, (%r12,%rbx,8)
incq %rbx
cmpq %rbx, %r15
jne 0x11d97b
movq %r13, %rdi
callq 0xd220
movq %r12, %rdi
callq 0xd220
movq %rbp, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq