// File: HQarroum[P]thread-pool/examples/many-producers-many-consumers/main.cpp
// Function: main
int main() {
  // Producer and consumer thread pools.
  thread::pool::pool_t pool_of_consumers(5);
  thread::pool::pool_t pool_of_producers(5);

  // Counting the start time.
  auto start = std::chrono::high_resolution_clock::now();

  // Array of producer workers.
  auto producers = new std::function<void()>[workers_to_spawn];
  // Filling the array with the producers.
  std::fill_n(producers, workers_to_spawn, std::bind(producer, &pool_of_consumers));

  // Scheduling the producers.
  pool_of_producers.schedule_bulk(producers, workers_to_spawn);

  // Waiting for the producers to complete.
  pool_of_producers.stop().await();
  
  // Waiting for the consumers to complete.
  while (count < workers_to_spawn * work_by_worker)
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

  // Measuring and dumping the elapsed time.
  auto end = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double, std::milli> diff = end - start;
  std::cout << "Elasped time : " << diff.count() << " ms" << std::endl;

  // Deleting the producer array.
  delete[] producers;
  return (0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x630, %rsp            # imm = 0x630
movl $0x0, -0x4(%rbp)
leaq -0x2a0(%rbp), %rdi
movl $0x5, %esi
movq %rsi, -0x5a0(%rbp)
callq 0x3de0
movq -0x5a0(%rbp), %rsi
leaq -0x538(%rbp), %rdi
callq 0x3de0
jmp 0x35bf
callq 0x3050
movq %rax, -0x550(%rbp)
movl $0x7d08, %edi           # imm = 0x7D08
callq 0x3030
movq %rax, -0x5a8(%rbp)
jmp 0x35de
movq -0x5a8(%rbp), %rax
movq $0x3e8, (%rax)          # imm = 0x3E8
addq $0x8, %rax
movq %rax, -0x5c0(%rbp)
movq %rax, %rcx
addq $0x7d00, %rcx           # imm = 0x7D00
movq %rcx, -0x5b8(%rbp)
movq %rax, -0x5b0(%rbp)
movq -0x5b0(%rbp), %rdi
movq %rdi, -0x5c8(%rbp)
callq 0x3ef0
movq -0x5c8(%rbp), %rax
movq -0x5b8(%rbp), %rcx
addq $0x20, %rax
cmpq %rcx, %rax
movq %rax, -0x5b0(%rbp)
jne 0x360f
movq -0x5c0(%rbp), %rax
movq %rax, -0x558(%rbp)
movq -0x558(%rbp), %rax
movq %rax, -0x5d0(%rbp)
leaq -0x2a0(%rbp), %rax
movq %rax, -0x570(%rbp)
leaq -0x141(%rip), %rsi      # 0x3530
leaq -0x568(%rbp), %rdi
leaq -0x570(%rbp), %rdx
callq 0x3f90
jmp 0x3686
movq -0x5d0(%rbp), %rdi
movl $0x3e8, %esi            # imm = 0x3E8
leaq -0x568(%rbp), %rdx
callq 0x3f30
jmp 0x36a0
movq -0x558(%rbp), %rsi
leaq -0x538(%rbp), %rdi
movq %rdi, -0x5d8(%rbp)
movl $0x3e8, %edx            # imm = 0x3E8
callq 0x3fd0
movq -0x5d8(%rbp), %rdi
callq 0x4020
movq %rax, %rdi
callq 0x4060
jmp 0x36d5
jmp 0x36d7
leaq 0x21b42(%rip), %rdi     # 0x25220
callq 0x40d0
cmpq $0xf4240, %rax          # imm = 0xF4240
jae 0x3754
movl $0x64, -0x57c(%rbp)
leaq -0x578(%rbp), %rdi
leaq -0x57c(%rbp), %rsi
callq 0x4200
jmp 0x370a
leaq -0x578(%rbp), %rdi
callq 0x4150
jmp 0x3718
jmp 0x36d7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x540(%rbp)
movl %eax, -0x544(%rbp)
jmp 0x38e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x540(%rbp)
movl %eax, -0x544(%rbp)
leaq -0x538(%rbp), %rdi
callq 0x42f0
jmp 0x38e4
callq 0x3050
movq %rax, -0x588(%rbp)
leaq -0x588(%rbp), %rdi
leaq -0x550(%rbp), %rsi
callq 0x4220
movq %rax, -0x5e0(%rbp)
jmp 0x377c
movq -0x5e0(%rbp), %rax
movq %rax, -0x598(%rbp)
leaq -0x590(%rbp), %rdi
leaq -0x598(%rbp), %rsi
callq 0x4270
jmp 0x379f
movq 0x21812(%rip), %rdi     # 0x24fb8
leaq 0x15bd7(%rip), %rsi     # 0x19384
callq 0x3250
movq %rax, -0x5e8(%rbp)
jmp 0x37bb
leaq -0x590(%rbp), %rdi
callq 0x42b0
movsd %xmm0, -0x5f0(%rbp)
jmp 0x37d1
movsd -0x5f0(%rbp), %xmm0
movq -0x5e8(%rbp), %rdi
callq 0x3390
movq %rax, -0x5f8(%rbp)
jmp 0x37ee
movq -0x5f8(%rbp), %rdi
leaq 0x15b98(%rip), %rsi     # 0x19394
callq 0x3250
movq %rax, -0x600(%rbp)
jmp 0x380a
movq -0x600(%rbp), %rdi
movq 0x21748(%rip), %rsi     # 0x24f60
callq 0x3280
jmp 0x381f
movq -0x558(%rbp), %rax
movq %rax, -0x608(%rbp)
cmpq $0x0, %rax
je 0x38b9
movq -0x608(%rbp), %rcx
movq %rcx, %rax
addq $-0x8, %rax
movq %rax, -0x620(%rbp)
movq -0x8(%rcx), %rdx
movq %rdx, -0x618(%rbp)
shlq $0x5, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x610(%rbp)
je 0x389e
movq -0x610(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x628(%rbp)
callq 0x42d0
movq -0x608(%rbp), %rcx
movq -0x628(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x610(%rbp)
jne 0x386d
movq -0x620(%rbp), %rdi
movq -0x618(%rbp), %rsi
shlq $0x5, %rsi
addq $0x8, %rsi
callq 0x33b0
movl $0x0, -0x4(%rbp)
leaq -0x538(%rbp), %rdi
callq 0x42f0
leaq -0x2a0(%rbp), %rdi
callq 0x42f0
movl -0x4(%rbp), %eax
addq $0x630, %rsp            # imm = 0x630
popq %rbp
retq
leaq -0x2a0(%rbp), %rdi
callq 0x42f0
movq -0x540(%rbp), %rdi
callq 0x3370
nopl (%rax)