// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %ecx, %r14d
movl %edx, %ecx
movq %rdi, %rbx
movl %esi, (%rdi)
movl %edx, 0x4(%rdi)
movl %r8d, 0x28(%rdi)
pushq $0x8
popq %rdi
movl %esi, %eax
cltd
idivl %edi
cvtsi2ss %esi, %xmm1
andl $0x7, %esi
cmpl $0x1, %esi
sbbl $-0x1, %eax
cvtsi2sd %r14d, %xmm2
mulsd %xmm0, %xmm2
cvttsd2si %xmm2, %edx
leal -0x1(%r14), %esi
cmpl %esi, %edx
cmovll %edx, %esi
cmpl $0x2, %esi
pushq $0x1
popq %rdx
cmovgel %esi, %edx
movl %eax, 0x8(%rbx)
cvtsi2ss %edx, %xmm2
cvtsi2ss %ecx, %xmm0
divss %xmm1, %xmm0
movss %xmm2, 0x4(%rsp)
mulss %xmm2, %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jb 0x379b
sqrtss %xmm0, %xmm0
jmp 0x37a0
callq 0x2240
movss %xmm0, (%rsp)
callq 0x2080
cvttss2si %xmm0, %r15d
movl %r15d, 0xc(%rbx)
movss 0x4(%rsp), %xmm0
divss (%rsp), %xmm0
callq 0x2080
cvttss2si %xmm0, %eax
movl %eax, 0x10(%rbx)
leal 0x1(%r15), %edx
movl %edx, %ebp
imull %eax, %ebp
leal 0x1(%rax), %esi
movl %esi, %ecx
imull %r15d, %ecx
cmpl %r14d, %ebp
jg 0x37ec
cmpl %r14d, %ecx
jg 0x37ec
cmpl %ecx, %ebp
jg 0x37fe
jmp 0x3803
cmpl %r14d, %ebp
jle 0x37fe
cmpl %r14d, %ecx
jle 0x3803
imull %r15d, %eax
movl %eax, %ebp
jmp 0x3808
movl %edx, 0xc(%rbx)
jmp 0x3808
movl %esi, 0x10(%rbx)
movl %ecx, %ebp
movl %ebp, 0x14(%rbx)
movl %ebp, 0x18(%rbx)
subl %ebp, %r14d
movl %r14d, 0x1c(%rbx)
movslq %r14d, %r14
leaq (,%r14,4), %rax
xorl %r15d, %r15d
testl %r14d, %r14d
pushq $-0x1
popq %rdi
cmovnsq %rax, %rdi
cmovlel %r15d, %r14d
callq 0x2030
movq %rax, 0x20(%rbx)
movl %ebp, %ecx
cmpq %r15, %r14
je 0x384e
leal (%rcx,%r15), %edx
movl %edx, (%rax,%r15,4)
incq %r15
jmp 0x383c
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop