// File: /workspace/github_c_makefile_star2_O0/johsteffens[P]beth/lib/bcore/bcore_tbman.c
// Function: token_manager_s_create
static token_manager_s* token_manager_s_create
    (
        uz_t pool_size,
        uz_t block_size,
        bl_t align,
        down_manager_s* down_manager,
        bcore_mutex_s* mutex
    )
{
    if( ( pool_size & ( pool_size - 1 ) ) != 0 ) ERR( "pool_size %zu is not a power of two", pool_size );
    uz_t stack_size = pool_size / block_size;
    if( stack_size > 0x10000 ) ERR( "stack_size %zu exceeds 0x10000", stack_size );
    uz_t reserved_size   = sizeof( token_manager_s ) + sizeof( u1_t ) * stack_size;
    uz_t reserved_blocks = reserved_size / block_size + ( ( reserved_size % block_size ) > 0 );
    if( stack_size < ( reserved_blocks + 1 ) ) ERR( "pool_size %zu is too small", pool_size );

    token_manager_s* o;
    if( align )
    {
        /* We align to the entire pool_size (not just block_size).
         * This is to enable quick O(1) location of the token manager from any memory instance
         * by computing the next lower alignment point form a given address.
         */
        o = aligned_alloc( pool_size, pool_size );
        if( !o ) ERR( "Failed aligned allocating %zu bytes", pool_size );
    }
    else
    {
        o = aligned_alloc( TBMAN_ALIGN, pool_size );
        if( !o ) ERR( "Failed allocating %zu bytes", pool_size );
    }

    token_manager_s_init( o );

    /* We explicitly check alignment allowing for unexpected behavior of aligned_alloc.
     * If alignment (according to tbman's definition) fails, o->aligned is set to 'false' and
     * tbman falls back to a slightly slower btree-search to locate the token manager.
     */
    o->aligned = ( ( intptr_t )o & ( intptr_t )( pool_size - 1 ) ) == 0;
    o->pool_size = pool_size;
    o->block_size = block_size;
    o->stack_size = stack_size;
    o->stack_index = 0;
    for( uz_t i = 0; i < o->stack_size; i++ ) o->token_stack[ i ] = ( i + reserved_blocks ) < stack_size ? ( i + reserved_blocks ) : 0;
    o->down_manager = down_manager;
    o->mutex = mutex;
    return o;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x10db79
movq -0x8(%rbp), %r8
leaq 0x49e81(%rip), %rdi     # 0x1579e0
leaq 0x49837(%rip), %rsi     # 0x15739d
movl $0x10c, %edx            # imm = 0x10C
leaq 0x49e85(%rip), %rcx     # 0x1579f7
movb $0x0, %al
callq 0x9cf40
movq -0x8(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq %rax, -0x30(%rbp)
cmpq $0x10000, -0x30(%rbp)   # imm = 0x10000
jbe 0x10dbb8
movq -0x30(%rbp), %r8
leaq 0x49e42(%rip), %rdi     # 0x1579e0
leaq 0x497f8(%rip), %rsi     # 0x15739d
movl $0x10e, %edx            # imm = 0x10E
leaq 0x49e6a(%rip), %rcx     # 0x157a1b
movb $0x0, %al
callq 0x9cf40
movq -0x30(%rbp), %rax
shlq %rax
addq $0x48, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq %rax, -0x58(%rbp)
movq -0x38(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x10(%rbp)
movq -0x58(%rbp), %rax
cmpq $0x0, %rdx
seta %cl
andb $0x1, %cl
movzbl %cl, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movq -0x40(%rbp), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jae 0x10dc34
movq -0x8(%rbp), %r8
leaq 0x49dc6(%rip), %rdi     # 0x1579e0
leaq 0x4977c(%rip), %rsi     # 0x15739d
movl $0x111, %edx            # imm = 0x111
leaq 0x49e0d(%rip), %rcx     # 0x157a3a
movb $0x0, %al
callq 0x9cf40
testb $0x1, -0x11(%rbp)
je 0x10dc79
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x41c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x10dc77
movq -0x8(%rbp), %r8
leaq 0x49d83(%rip), %rdi     # 0x1579e0
leaq 0x49739(%rip), %rsi     # 0x15739d
movl $0x11b, %edx            # imm = 0x11B
leaq 0x49de5(%rip), %rcx     # 0x157a55
movb $0x0, %al
callq 0x9cf40
jmp 0x10dcb9
movq -0x8(%rbp), %rsi
movl $0x100, %edi            # imm = 0x100
callq 0x41c0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x10dcb7
movq -0x8(%rbp), %r8
leaq 0x49d43(%rip), %rdi     # 0x1579e0
leaq 0x496f9(%rip), %rsi     # 0x15739d
movl $0x120, %edx            # imm = 0x120
leaq 0x496fb(%rip), %rcx     # 0x1573ab
movb $0x0, %al
callq 0x9cf40
jmp 0x10dcb9
movq -0x48(%rbp), %rdi
callq 0x10dda0
movq -0x48(%rbp), %rax
movq -0x8(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
sete %cl
movq -0x48(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x14(%rax)
movq -0x8(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x30(%rbp), %rax
movw %ax, %cx
movq -0x48(%rbp), %rax
movw %cx, 0x10(%rax)
movq -0x48(%rbp), %rax
movw $0x0, 0x12(%rax)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
cmpq %rcx, %rax
jae 0x10dd71
movq -0x50(%rbp), %rax
addq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0x10dd47
movq -0x50(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x10dd4f
xorl %eax, %eax
movq %rax, -0x60(%rbp)
jmp 0x10dd4f
movq -0x60(%rbp), %rax
movw %ax, %dx
movq -0x48(%rbp), %rax
movq -0x50(%rbp), %rcx
movw %dx, 0x48(%rax,%rcx,2)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x10dd1a
movq -0x20(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x28(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x48(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)