// File: /workspace/github_c_makefile_star2_O2/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 $0x58, %rsp
movl %r8d, %ebx
movq %rcx, %r14
movq %rdx, 0x18(%rsp)
movq %rsi, %rbp
movq %rdi, 0x10(%rsp)
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x8eb65
movq %rax, 0x40(%rsp)
leaq (,%rbp,8), %r15
movq %r15, %rdi
callq 0xd160
movq %rax, (%rsp)
movq %r15, %rdi
callq 0xd160
movq %rax, 0x8(%rsp)
movq (%rsp), %rax
cmpq %r12, %rbp
je 0x95f08
andq $0x0, (%rax,%r12,8)
incq %r12
jmp 0x95ef9
xorl %eax, %eax
movq 0x8(%rsp), %rcx
cmpq %rax, %rbp
je 0x95f1e
andq $0x0, (%rcx,%rax,8)
incq %rax
jmp 0x95f0f
cvtsi2sd %r14, %xmm0
movsd %xmm0, 0x38(%rsp)
xorl %r15d, %r15d
movq %rbp, 0x28(%rsp)
cmpq 0x18(%rsp), %r15
je 0x96277
xorl %r12d, %r12d
movq %r15, 0x20(%rsp)
cmpq %rbp, %r12
je 0x9626f
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 0x8(%rsp), %rax
movq (%rax,%rdx,8), %r14
testq %r14, %r14
movq %r12, 0x30(%rsp)
je 0x9600b
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
movq (%rsp), %rax
movq (%rax,%r13,8), %rbp
xorl %r12d, %r12d
cmpq %r12, %r14
je 0x95fff
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,%r12), %r8d
movzbl %r15b, %r9d
cmpl %r8d, %r9d
je 0x95ffa
leaq 0x357a1(%rip), %rdi     # 0xcb781
leaq 0x34d36(%rip), %rsi     # 0xcad1d
movl $0xae9, %edx            # imm = 0xAE9
leaq 0x357a4(%rip), %rcx     # 0xcb797
xorl %eax, %eax
callq 0x60031
incq %r12
jmp 0x95fab
movq 0x20(%rsp), %r15
movq 0x30(%rsp), %r12
jmp 0x96013
movq (%rsp), %rax
movq (%rax,%r13,8), %rbp
movq 0x8(%rsp), %rax
leaq (%rax,%r13,8), %r14
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 0x9614c
testb $0x20, %bl
jne 0x961ef
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 0x34c8b(%rip), %xmm1    # 0xcacf0
movsd 0x38(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1e65c(%rip), %xmm0    # 0xb46e0
cvttsd2si %xmm0, %r15
andq %rcx, %r15
orq %rax, %r15
andq $0x0, 0x48(%rsp)
movq (%r14), %rsi
movq %rbp, %rdi
movq %r15, %rdx
leaq 0x48(%rsp), %rcx
callq *0x10(%rsp)
movq %rax, %rbp
movq (%rsp), %rax
movq %rbp, (%rax,%r13,8)
movq %r14, 0x50(%rsp)
movq (%r14), %r14
testq %r14, %r14
je 0x96208
cmpq %r15, %r14
jae 0x96208
testq %rbp, %rbp
je 0x96208
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 %r12d, %r12d
cmpq %r12, %r14
je 0x96208
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,%r12), %r8d
movzbl %r15b, %r9d
cmpl %r8d, %r9d
je 0x96147
leaq 0x35654(%rip), %rdi     # 0xcb781
leaq 0x34be9(%rip), %rsi     # 0xcad1d
movl $0xb1e, %edx            # imm = 0xB1E
leaq 0x35657(%rip), %rcx     # 0xcb797
xorl %eax, %eax
callq 0x60031
incq %r12
jmp 0x960f4
movl %ebx, %eax
cvtsi2sd %rax, %xmm1
mulsd 0x34b95(%rip), %xmm1    # 0xcacf0
movsd 0x38(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1e566(%rip), %xmm0    # 0xb46e0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
xorl %edi, %edi
xorl %esi, %esi
movq %r14, %rcx
callq *0x10(%rsp)
movq (%rsp), %rcx
movq %rax, (%rcx,%r13,8)
movq (%r14), %rcx
testq %rcx, %rcx
je 0x96262
leal 0x1(%r13), %edx
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
xorl %esi, %esi
movq 0x28(%rsp), %rbp
cmpq %rsi, %rcx
je 0x96267
movl %edx, %edi
shrl $0x7, %edi
xorl %edx, %edi
movl %edi, %r8d
shll $0x19, %r8d
xorl %edi, %r8d
movl %r8d, %edx
shrl $0xc, %edx
xorl %r8d, %edx
movb %dl, (%rax,%rsi)
incq %rsi
jmp 0x961c4
movq (%r14), %rsi
movq %rbp, %rdi
xorl %edx, %edx
movq %r14, %rcx
callq *0x10(%rsp)
movq (%rsp), %rcx
movq %rax, (%rcx,%r13,8)
jmp 0x96262
movq 0x48(%rsp), %rax
movq 0x50(%rsp), %rcx
movq %rax, (%rcx)
testq %rax, %rax
movq 0x20(%rsp), %r15
movq 0x30(%rsp), %r12
je 0x96262
leal 0x1(%r13), %ecx
movl %ecx, %edx
shrl $0x7, %edx
xorl %ecx, %edx
movl %edx, %esi
shll $0x19, %esi
xorl %edx, %esi
movl %esi, %ecx
shrl $0xc, %ecx
xorl %esi, %ecx
xorl %edx, %edx
cmpq %rdx, %rax
je 0x96262
movl %ecx, %esi
shrl $0x7, %esi
xorl %ecx, %esi
movl %esi, %edi
shll $0x19, %edi
xorl %esi, %edi
movl %edi, %ecx
shrl $0xc, %ecx
xorl %edi, %ecx
movb %cl, (%rbp,%rdx)
incq %rdx
jmp 0x9623f
movq 0x28(%rsp), %rbp
incq %r12
jmp 0x95f44
incq %r15
jmp 0x95f31
xorl %r12d, %r12d
callq 0xd340
movq %rax, %r14
cmpq 0x18(%rsp), %r12
je 0x96337
movq %rbp, %r13
subq $0x1, %r13
jb 0x9632f
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 (%rsp), %rax
movq (%rax,%rdx,8), %rdi
testq %rdi, %rdi
je 0x962d8
movq 0x8(%rsp), %rax
leaq (%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rsi
xorl %edx, %edx
jmp 0x9631e
movl %ebx, %eax
cvtsi2sd %rax, %xmm1
mulsd 0x34a09(%rip), %xmm1    # 0xcacf0
movsd 0x38(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x1e3de(%rip), %xmm0    # 0xb46e0
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
movq 0x8(%rsp), %rax
leaq (%rax,%r15,8), %rcx
xorl %edi, %edi
xorl %esi, %esi
callq *0x10(%rsp)
movq (%rsp), %rcx
movq %rax, (%rcx,%r15,8)
jmp 0x96290
incq %r12
jmp 0x96282
callq 0xd340
subq %r14, %rax
cvtsi2sd %rax, %xmm0
movq %rbp, %rax
imulq 0x18(%rsp), %rax
imulq $0xf4240, %rax, %rax    # imm = 0xF4240
cvtsi2sd %rax, %xmm1
movsd %xmm1, 0x30(%rsp)
divsd %xmm1, %xmm0
leaq 0x35446(%rip), %rsi     # 0xcb7b0
movq 0x40(%rsp), %rdi
movb $0x1, %al
callq 0x8f42b
xorl %r12d, %r12d
callq 0xd340
movq %rax, 0x20(%rsp)
movq (%rsp), %r14
movq %rbp, %r13
cmpq 0x18(%rsp), %r12
je 0x96431
subq $0x1, %r13
jb 0x96429
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
cvtsi2sd %rbx, %xmm1
mulsd 0x3490f(%rip), %xmm1    # 0xcacf0
movsd 0x38(%rsp), %xmm0
callq 0xd470
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1e2e0(%rip), %xmm0    # 0xb46e0
cvttsd2si %xmm0, %rdx
andq %rcx, %rdx
orq %rax, %rdx
movq (%r14,%r15,8), %rdi
movq 0x8(%rsp), %rax
leaq (%rax,%r15,8), %rcx
movq (%rax,%r15,8), %rsi
callq *0x10(%rsp)
movq %rax, (%r14,%r15,8)
jmp 0x96395
incq %r12
jmp 0x96387
callq 0xd340
subq 0x20(%rsp), %rax
cvtsi2sd %rax, %xmm0
divsd 0x30(%rsp), %xmm0
leaq 0x35382(%rip), %rsi     # 0xcb7cf
movq 0x40(%rsp), %rdi
movb $0x1, %al
callq 0x8f42b
xorl %ebx, %ebx
movq (%rsp), %r14
cmpq %rbx, %rbp
je 0x96482
movq (%r14,%rbx,8), %rdi
movq 0x8(%rsp), %rax
movq (%rax,%rbx,8), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *0x10(%rsp)
movq %rax, (%r14,%rbx,8)
incq %rbx
jmp 0x9645f
movq 0x8(%rsp), %rdi
callq 0xd220
movq (%rsp), %rdi
callq 0xd220
movq 0x40(%rsp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq