// File: kaityo256[P]cps/cps.cpp
// Function: manager(int)
void manager(const int procs) {
  const int num_tasks = command_list.size();
  assign_list.resize(procs, -1);
  start_time.resize(procs);
  ellapsed_time.resize(num_tasks);
  int task_index = 0;
  auto timer_start = std::chrono::system_clock::now();
  // Distribute Tasks
  while (task_index < num_tasks) {
    MPI_Status st;
    int isReady = 0;
    MPI_Recv(&isReady, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &st);
    int i = st.MPI_SOURCE;
    if (assign_list[i] != -1) {
      auto start = start_time[i];
      double elapsed = get_time(start);
      ellapsed_time[assign_list[i]] = elapsed;
      debug_printf("task %d assigned to %d is finished at %f\n", task_index, i, get_time(timer_start));
      assign_list[i] = -1;
    }
    // Assign task_index-th task to the i-th process
    assign_list[i] = task_index;
    start_time[i] = std::chrono::system_clock::now();
    debug_printf("task %d is assignd to %d at %f\n", task_index, i, get_time(timer_start));
    int len = command_list[task_index].length() + 1;
    MPI_Send(&len, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
    MPI_Send(command_list[task_index].data(), len, MPI_CHAR, i, 0, MPI_COMM_WORLD);
    task_index++;
  }
  // Complete Notification
  int finish_check = procs - 1;

  while (finish_check > 0) {
    MPI_Status st;
    int dummy = 0;
    int recv = 0;
    MPI_Recv(&recv, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &st);
    int i = st.MPI_SOURCE;
    MPI_Send(&dummy, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
    finish_check--;
    if (assign_list[i] != -1) {
      auto start = start_time[i];
      double elapsed = get_time(start);
      ellapsed_time[assign_list[i]] = elapsed;
      debug_printf("task %d assigned to %d is finished at %f\n", task_index, i, get_time(timer_start));
      assign_list[i] = -1;
    }
  }
  // Generate Log
  std::ofstream ofs("cps.log");
  ofs << "Number of tasks : " << num_tasks << std::endl;
  ofs << "Number of processes : " << procs << std::endl;
  double total = std::accumulate(ellapsed_time.begin(), ellapsed_time.end(), 0.0);
  ofs << "Total execution time: " << total << " [s]" << std::endl;
  double elapsed = get_time(timer_start);
  ofs << "Elapsed time: " << elapsed << " [s]" << std::endl;
  double eff = total / (elapsed * (procs - 1));
  ofs << "Parallel Efficiency : " << eff << std::endl;
  ofs << std::endl;
  ofs << "Task list:" << std::endl;
  ofs << "Command : Elapsed time" << std::endl;
  for (int i = 0; i < num_tasks; i++) {
    ofs << command_list[i] << " : " << ellapsed_time[i] << " [s]" << std::endl;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3f0, %rsp            # imm = 0x3F0
movl %edi, -0x4(%rbp)
leaq 0x12753(%rip), %rdi     # 0x1b678
callq 0xa600
movl %eax, -0x8(%rbp)
movslq -0x4(%rbp), %rsi
movl $0xffffffff, -0xc(%rbp) # imm = 0xFFFFFFFF
leaq 0x12751(%rip), %rdi     # 0x1b690
leaq -0xc(%rbp), %rdx
callq 0xa620
movslq -0x4(%rbp), %rsi
leaq 0x12755(%rip), %rdi     # 0x1b6a8
callq 0xa6d0
movslq -0x8(%rbp), %rsi
leaq 0x1275d(%rip), %rdi     # 0x1b6c0
callq 0xa760
movl $0x0, -0x10(%rbp)
callq 0x8060
movq %rax, -0x18(%rbp)
movl -0x10(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x9174
movl $0x0, -0x34(%rbp)
leaq -0x34(%rbp), %rdi
movl $0x1, %esi
movq 0x1202d(%rip), %rdx     # 0x1afc8
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %r8d, %r8d
movq 0x11ff6(%rip), %r9      # 0x1afa0
leaq -0x30(%rbp), %rax
movq %rax, (%rsp)
callq 0x84e0
movl -0x30(%rbp), %eax
movl %eax, -0x38(%rbp)
movslq -0x38(%rbp), %rsi
leaq 0x126c8(%rip), %rdi     # 0x1b690
callq 0xa7f0
cmpl $-0x1, (%rax)
je 0x907f
movslq -0x38(%rbp), %rsi
leaq 0x126c7(%rip), %rdi     # 0x1b6a8
callq 0xa810
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0x48(%rbp)
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x320(%rbp)
movslq -0x38(%rbp), %rsi
leaq 0x12675(%rip), %rdi     # 0x1b690
callq 0xa7f0
movslq (%rax), %rsi
leaq 0x12696(%rip), %rdi     # 0x1b6c0
callq 0xa830
movsd -0x320(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0x58(%rbp)
leaq 0x9fb8(%rip), %rdi      # 0x13010
leaq -0x10(%rbp), %rsi
leaq -0x38(%rbp), %rdx
leaq -0x58(%rbp), %rcx
callq 0xa850
movslq -0x38(%rbp), %rsi
leaq 0x1261c(%rip), %rdi     # 0x1b690
callq 0xa7f0
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
movl -0x10(%rbp), %eax
movl %eax, -0x324(%rbp)
movslq -0x38(%rbp), %rsi
leaq 0x125fd(%rip), %rdi     # 0x1b690
callq 0xa7f0
movl -0x324(%rbp), %ecx
movl %ecx, (%rax)
callq 0x8060
movq %rax, -0x68(%rbp)
movslq -0x38(%rbp), %rsi
leaq 0x125f4(%rip), %rdi     # 0x1b6a8
callq 0xa810
movq -0x68(%rbp), %rcx
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0x70(%rbp)
leaq 0x9f5d(%rip), %rdi      # 0x1303a
leaq -0x10(%rbp), %rsi
leaq -0x38(%rbp), %rdx
leaq -0x70(%rbp), %rcx
callq 0xa850
movslq -0x10(%rbp), %rsi
leaq 0x1257f(%rip), %rdi     # 0x1b678
callq 0xa870
movq %rax, %rdi
callq 0x8980
addq $0x1, %rax
movl %eax, -0x7c(%rbp)
movl -0x38(%rbp), %ecx
leaq -0x7c(%rbp), %rdi
movl $0x1, %esi
movq 0x11ea8(%rip), %rdx     # 0x1afc8
xorl %r8d, %r8d
movq 0x11e76(%rip), %r9      # 0x1afa0
callq 0x81e0
movslq -0x10(%rbp), %rsi
leaq 0x1253e(%rip), %rdi     # 0x1b678
callq 0xa870
movq %rax, %rdi
callq 0x87c0
movq %rax, %rdi
movl -0x7c(%rbp), %esi
movl -0x38(%rbp), %ecx
movq 0x11e31(%rip), %rdx     # 0x1af88
xorl %r8d, %r8d
movq 0x11e3f(%rip), %r9      # 0x1afa0
callq 0x81e0
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x8f78
movl -0x4(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x80(%rbp)
cmpl $0x0, -0x80(%rbp)
jle 0x92fe
movl $0x0, -0x9c(%rbp)
movl $0x0, -0xa0(%rbp)
leaq -0xa0(%rbp), %rdi
movl $0x1, %esi
movq 0x11e1a(%rip), %rdx     # 0x1afc8
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %r8d, %r8d
movq 0x11de3(%rip), %r9      # 0x1afa0
leaq -0x98(%rbp), %rax
movq %rax, (%rsp)
callq 0x84e0
movl -0x98(%rbp), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %ecx
leaq -0x9c(%rbp), %rdi
movl $0x1, %esi
movq 0x11dd6(%rip), %rdx     # 0x1afc8
xorl %r8d, %r8d
movq 0x11da4(%rip), %r9      # 0x1afa0
callq 0x81e0
movl -0x80(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x80(%rbp)
movslq -0xa4(%rbp), %rsi
leaq 0x12478(%rip), %rdi     # 0x1b690
callq 0xa7f0
cmpl $-0x1, (%rax)
je 0x92f9
movslq -0xa4(%rbp), %rsi
leaq 0x12474(%rip), %rdi     # 0x1b6a8
callq 0xa810
movq (%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0xb8(%rbp)
movsd -0xb8(%rbp), %xmm0
movsd %xmm0, -0x330(%rbp)
movslq -0xa4(%rbp), %rsi
leaq 0x1240d(%rip), %rdi     # 0x1b690
callq 0xa7f0
movslq (%rax), %rsi
leaq 0x1242e(%rip), %rdi     # 0x1b6c0
callq 0xa830
movsd -0x330(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0xc8(%rbp)
leaq 0x9d47(%rip), %rdi      # 0x13010
leaq -0x10(%rbp), %rsi
leaq -0xa4(%rbp), %rdx
leaq -0xc8(%rbp), %rcx
callq 0xa850
movslq -0xa4(%rbp), %rsi
leaq 0x123a2(%rip), %rdi     # 0x1b690
callq 0xa7f0
movl $0xffffffff, (%rax)     # imm = 0xFFFFFFFF
jmp 0x917d
leaq 0x9d55(%rip), %rsi      # 0x1305a
leaq -0x2d0(%rbp), %rdi
movq %rdi, -0x340(%rbp)
movl $0x10, %edx
callq 0x86a0
movq -0x340(%rbp), %rdi
leaq 0x9d37(%rip), %rsi      # 0x13062
callq 0x85f0
movq %rax, -0x338(%rbp)
jmp 0x9339
movq -0x338(%rbp), %rdi
movl -0x8(%rbp), %esi
callq 0x8b10
movq %rax, -0x348(%rbp)
jmp 0x9351
movq -0x348(%rbp), %rdi
movq 0x11c39(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x9366
leaq 0x9d08(%rip), %rsi      # 0x13075
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x350(%rbp)
jmp 0x9382
movq -0x350(%rbp), %rdi
movl -0x4(%rbp), %esi
callq 0x8b10
movq %rax, -0x358(%rbp)
jmp 0x939a
movq -0x358(%rbp), %rdi
movq 0x11bf0(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x93af
leaq 0x1230a(%rip), %rdi     # 0x1b6c0
movq %rdi, -0x368(%rbp)
callq 0xa8f0
movq -0x368(%rbp), %rdi
movq %rax, -0x2f0(%rbp)
callq 0xa920
movq %rax, -0x2f8(%rbp)
movq -0x2f0(%rbp), %rdi
movq -0x2f8(%rbp), %rsi
xorps %xmm0, %xmm0
callq 0xa890
movsd %xmm0, -0x360(%rbp)
jmp 0x93fc
movsd -0x360(%rbp), %xmm0
movsd %xmm0, -0x2e8(%rbp)
leaq 0x9c79(%rip), %rsi      # 0x1308c
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x370(%rbp)
jmp 0x9428
movq -0x370(%rbp), %rdi
movsd -0x2e8(%rbp), %xmm0
callq 0x8c00
movq %rax, -0x378(%rbp)
jmp 0x9445
movq -0x378(%rbp), %rdi
leaq 0x9c50(%rip), %rsi      # 0x130a3
callq 0x85f0
movq %rax, -0x380(%rbp)
jmp 0x9461
movq -0x380(%rbp), %rdi
movq 0x11b29(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x9476
movq -0x18(%rbp), %rax
movq %rax, -0x308(%rbp)
movq -0x308(%rbp), %rdi
callq 0x8eb0
movsd %xmm0, -0x388(%rbp)
jmp 0x9497
movsd -0x388(%rbp), %xmm0
movsd %xmm0, -0x300(%rbp)
leaq 0x9bfa(%rip), %rsi      # 0x130a8
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x390(%rbp)
jmp 0x94c3
movq -0x390(%rbp), %rdi
movsd -0x300(%rbp), %xmm0
callq 0x8c00
movq %rax, -0x398(%rbp)
jmp 0x94e0
movq -0x398(%rbp), %rdi
leaq 0x9bb5(%rip), %rsi      # 0x130a3
callq 0x85f0
movq %rax, -0x3a0(%rbp)
jmp 0x94fc
movq -0x3a0(%rbp), %rdi
movq 0x11a8e(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x9511
movsd -0x2e8(%rbp), %xmm0
movsd -0x300(%rbp), %xmm1
movl -0x4(%rbp), %eax
decl %eax
cvtsi2sd %eax, %xmm2
mulsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x310(%rbp)
leaq 0x9b76(%rip), %rsi      # 0x130b7
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x3a8(%rbp)
jmp 0x9556
movq -0x3a8(%rbp), %rdi
movsd -0x310(%rbp), %xmm0
callq 0x8c00
movq %rax, -0x3b0(%rbp)
jmp 0x9573
movq -0x3b0(%rbp), %rdi
movq 0x11a17(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x9588
movq 0x11a09(%rip), %rsi     # 0x1af98
leaq -0x2d0(%rbp), %rdi
callq 0x8620
jmp 0x959d
leaq 0x9b2a(%rip), %rsi      # 0x130ce
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x3b8(%rbp)
jmp 0x95b9
movq -0x3b8(%rbp), %rdi
movq 0x119d1(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x95ce
leaq 0x9b04(%rip), %rsi      # 0x130d9
leaq -0x2d0(%rbp), %rdi
callq 0x85f0
movq %rax, -0x3c0(%rbp)
jmp 0x95ea
movq -0x3c0(%rbp), %rdi
movq 0x119a0(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x95ff
movl $0x0, -0x314(%rbp)
movl -0x314(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x96f2
movslq -0x314(%rbp), %rsi
leaq 0x12052(%rip), %rdi     # 0x1b678
callq 0xa870
movq %rax, %rsi
leaq -0x2d0(%rbp), %rdi
callq 0x8560
movq %rax, -0x3c8(%rbp)
jmp 0x9643
movq -0x3c8(%rbp), %rdi
leaq 0x9a37(%rip), %rsi      # 0x13088
callq 0x85f0
movq %rax, -0x3d0(%rbp)
jmp 0x965f
movslq -0x314(%rbp), %rsi
leaq 0x12053(%rip), %rdi     # 0x1b6c0
callq 0xa830
movq -0x3d0(%rbp), %rdi
movsd (%rax), %xmm0
callq 0x8c00
movq %rax, -0x3d8(%rbp)
jmp 0x968b
movq -0x3d8(%rbp), %rdi
leaq 0x9a0a(%rip), %rsi      # 0x130a3
callq 0x85f0
movq %rax, -0x3e0(%rbp)
jmp 0x96a7
movq -0x3e0(%rbp), %rdi
movq 0x118e3(%rip), %rsi     # 0x1af98
callq 0x8620
jmp 0x96bc
jmp 0x96be
movl -0x314(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x314(%rbp)
jmp 0x9609
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x2d8(%rbp)
movl %eax, -0x2dc(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x8950
jmp 0x9707
leaq -0x2d0(%rbp), %rdi
callq 0x8950
addq $0x3f0, %rsp            # imm = 0x3F0
popq %rbp
retq
movq -0x2d8(%rbp), %rdi
callq 0x8b40
nopw %cs:(%rax,%rax)