// File: Gammelkebab[P]GameOfLife/src/main.cpp
// Function: main
int main(int argc, char **argv)
{
    MPI_Init(&argc, &argv);

    //time measurement
    double elapsed = 0;
    struct timeval begin, end;

    int proc_amt, proc_num;

    MPI_Comm_rank(MPI_COMM_WORLD, &proc_num);
    MPI_Comm_size(MPI_COMM_WORLD, &proc_amt);

    if (proc_num == 0)
    {
        printf("Processors: %d\n", proc_amt);
        printf("World size: %d x %d\n", GRIDSIZE_X, GRIDSIZE_Y);
        printf("Frames: %d\n", FRAMES);
        printf("Worker share: %f\n", WORKER_SHARE);
    }

    char processor_name[100];
    int processor_name_length;
    MPI_Get_processor_name(processor_name, &processor_name_length);

    MPI_Barrier(MPI_COMM_WORLD);

    /* Timer start */
    gettimeofday(&begin, NULL);

    Actor *actor = Actor::create(GRIDSIZE_X, GRIDSIZE_Y, proc_amt, proc_num, FRAMES, WORKER_SHARE);

    // Main execution loop
    for (int i = 0; i < FRAMES; i++)
    {
        /*
        if (proc_num == 0)
        {
            printf("round: %d of %d\n", i, FRAMES);
        }
        */
        actor->tick(i);
    }

    actor->finalize();

    MPI_Barrier(MPI_COMM_WORLD);

    /* Timer end */

    gettimeofday(&end, NULL);
    elapsed += (end.tv_sec - begin.tv_sec) + ((end.tv_usec - begin.tv_usec) / 1000000.0);
    if (proc_num == 0)
    {
        printf("Runtime: %.5fs\n", elapsed);
    }

    MPI_Finalize();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x8850
xorps %xmm0, %xmm0
movsd %xmm0, -0x18(%rbp)
movq 0xe1b3(%rip), %rdi      # 0x16fa8
leaq -0x40(%rbp), %rsi
callq 0x8840
movq 0xe1a3(%rip), %rdi      # 0x16fa8
leaq -0x3c(%rbp), %rsi
callq 0x86a0
cmpl $0x0, -0x40(%rbp)
jne 0x8e66
movl -0x3c(%rbp), %esi
leaq 0x81fa(%rip), %rdi      # 0x11018
movb $0x0, %al
callq 0x8040
leaq 0x81fc(%rip), %rdi      # 0x11028
movl $0x780, %esi            # imm = 0x780
movl $0x438, %edx            # imm = 0x438
movb $0x0, %al
callq 0x8040
leaq 0x81f9(%rip), %rdi      # 0x1103d
movl $0x384, %esi            # imm = 0x384
movb $0x0, %al
callq 0x8040
leaq 0x81f2(%rip), %rdi      # 0x11049
movsd 0x81a9(%rip), %xmm0     # 0x11008
movb $0x1, %al
callq 0x8040
leaq -0xb0(%rbp), %rdi
leaq -0xb4(%rbp), %rsi
callq 0x8680
movq 0xe128(%rip), %rdi      # 0x16fa8
callq 0x83a0
leaq -0x28(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8950
movl -0x3c(%rbp), %edx
movl -0x40(%rbp), %ecx
movl $0x780, %edi            # imm = 0x780
movl $0x438, %esi            # imm = 0x438
movl $0x384, %r8d            # imm = 0x384
movsd 0x8158(%rip), %xmm0     # 0x11008
callq 0xd980
movq %rax, -0xc0(%rbp)
movl $0x0, -0xc4(%rbp)
cmpl $0x384, -0xc4(%rbp)     # imm = 0x384
jge 0x8ef5
movq -0xc0(%rbp), %rdi
movl -0xc4(%rbp), %esi
movq (%rdi), %rax
callq *(%rax)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x8ec6
movq -0xc0(%rbp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0xe09f(%rip), %rdi      # 0x16fa8
callq 0x83a0
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x8950
movq -0x38(%rbp), %rax
subq -0x28(%rbp), %rax
cvtsi2sd %rax, %xmm0
movq -0x30(%rbp), %rax
subq -0x20(%rbp), %rax
cvtsi2sd %rax, %xmm1
movsd 0x80d3(%rip), %xmm2     # 0x11010
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
addsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x18(%rbp)
cmpl $0x0, -0x40(%rbp)
jne 0x8f68
movsd -0x18(%rbp), %xmm0
leaq 0x80fa(%rip), %rdi      # 0x1105b
movb $0x1, %al
callq 0x8040
callq 0x8410
movl -0x4(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopl (%rax)