// File: /workspace/github_cpp_makefile_star2_O1/Gammelkebab[P]GameOfLife/src/world/world.cpp
// Function: World::World(int, int, int, int, double)
World::World(int width, int height, int proc_amt, int total_rounds, double worker_share) : width(width), height(height), total_rounds(total_rounds)
{
    width_byte = width / 8 + (width % 8 == 0 ? 0 : 1);

    // Never have noone or everyone at work
    int worker_amt_tmp = btw(proc_amt * worker_share, 1, proc_amt - 1);

    // Distributes rows and columns proportionally to the overall pixel aspect ratio
    float rows_tmp = sqrt(worker_amt_tmp * ((float)height / width));
    rows = floor(rows_tmp);
    cols = floor(worker_amt_tmp / rows_tmp);

    // Try to create one more row or column (Might be possible due to flooring)
    int r1 = (rows + 1) * cols;
    int c1 = rows * (cols + 1);
    if (r1 <= proc_amt && c1 <= proc_amt)
    {
        if (r1 > c1)
        {
            rows++;
        }
        else
        {
            cols++;
        }
    }
    else if (r1 <= proc_amt)
    {
        rows++;
    }
    else if (c1 <= proc_amt)
    {
        cols++;
    }

    block_amt = rows * cols;
    worker_amt = block_amt; // There is one worker for every block
    writer_amt = proc_amt - worker_amt;

    // TODO
    // This enables scattering the writers amongst cores,
    // as long as the processor-core-distribution is known
    writer_nums = new int[writer_amt];
    for (int w = 0; w < writer_amt; w++)
    {
        writer_nums[w] = w + worker_amt; // Put writers behind workers
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movl %ecx, %r14d
movq %rdi, %rbx
movl %esi, (%rdi)
leal 0x7(%rsi), %eax
testl %esi, %esi
cmovnsl %esi, %eax
movl %edx, 0x4(%rdi)
cvtsi2ss %esi, %xmm1
sarl $0x3, %eax
movl %esi, %ecx
andl $0x7, %ecx
cmpl $0x1, %ecx
sbbl $-0x1, %eax
cvtsi2sd %r14d, %xmm2
movl %r8d, 0x28(%rdi)
mulsd %xmm0, %xmm2
cvttsd2si %xmm2, %ecx
leal -0x1(%r14), %esi
cmpl %esi, %ecx
cmovll %ecx, %esi
cmpl $0x2, %esi
movl $0x1, %ecx
cmovgel %esi, %ecx
movl %eax, 0x8(%rdi)
xorps %xmm2, %xmm2
cvtsi2ss %ecx, %xmm2
xorps %xmm0, %xmm0
cvtsi2ss %edx, %xmm0
divss %xmm1, %xmm0
movss %xmm2, 0xc(%rsp)
mulss %xmm2, %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jb 0x3ab0
sqrtss %xmm0, %xmm0
jmp 0x3ab5
callq 0x2240
movss %xmm0, 0x8(%rsp)
callq 0x2080
cvttss2si %xmm0, %r15d
movl %r15d, 0xc(%rbx)
movss 0xc(%rsp), %xmm0
divss 0x8(%rsp), %xmm0
callq 0x2080
cvttss2si %xmm0, %eax
movl %eax, 0x10(%rbx)
leal 0x1(%r15), %ecx
movl %ecx, %edx
imull %eax, %edx
incl %eax
imull %eax, %r15d
cmpl %r14d, %edx
jg 0x3b01
cmpl %r14d, %r15d
jg 0x3b01
cmpl %r15d, %edx
jle 0x3b0b
jmp 0x3b10
cmpl %r14d, %edx
jle 0x3b10
cmpl %r14d, %r15d
jg 0x3b13
movl %eax, 0x10(%rbx)
jmp 0x3b13
movl %ecx, 0xc(%rbx)
movl 0x10(%rbx), %eax
imull 0xc(%rbx), %eax
movl %eax, 0x14(%rbx)
movl %eax, 0x18(%rbx)
subl %eax, %r14d
movl %r14d, 0x1c(%rbx)
movslq %r14d, %rax
leaq (,%rax,4), %rcx
testl %eax, %eax
movq $-0x1, %rdi
cmovnsq %rcx, %rdi
callq 0x2030
movq %rax, 0x20(%rbx)
movslq 0x1c(%rbx), %rcx
testq %rcx, %rcx
jle 0x3b64
movl 0x18(%rbx), %edx
xorl %esi, %esi
leal (%rdx,%rsi), %edi
movl %edi, (%rax,%rsi,4)
incq %rsi
cmpq %rsi, %rcx
jne 0x3b56
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq