// File: /workspace/github_c_makefile_star2_O0/felipelouza[P]egap/threads.c
// Function: merger
void *merger(void *v)
{
  pc_system *pc = (pc_system *) v;
  g_data g, *buffer= (g_data *)pc->buffer;
  
  int tot=0;
  while(1) {
    int e=sem_wait(pc->ready); // wait there is something to do
    if(e) die("consumer wait");
    e = pthread_mutex_lock(&pc->cmutex); // get esclusive access to queue
    if(e) die("consumer lock");
    g = buffer[(pc->cindex)++ % pc->buf_size];
    e = pthread_mutex_unlock(&pc->cmutex); // fine accesso a zona comune
    if(e) die("consumer unlock");
    e = sem_post(pc->free_slots);
    if(e) die("consumer post");
    if(g.numBwt==0) break;
    else {
      if(g.verbose>2) printf("Working on range ["CUSTOM_FORMAT","CUSTOM_FORMAT")\n", g.symb_offset,g.symb_offset+g.mergeLen-1);
      if(pc->hm)  holtMcMillan(&g, false);
      else gap(&g, false);
      // merge statistics 
      for(int i=1;i<g.numBwt;i++) {
        g.bwtLen[0] += g.bwtLen[i];
        if(g.smallAlpha)
          for(int j=0;j<g.sizeOfAlpha;j++)
            g.bwtOcc[0][j] += g.bwtOcc[i][j];
      }
      assert(g.bwtLen[0]==g.mergeLen);
      tot++;
      // update # remaining segments when we reach 0 round is completed
      e = pthread_mutex_lock(&pc->remutex); 
      if(e) die("remaining locking in thread");
      if(--pc->remaining==0) {
        e = pthread_cond_signal(&pc->recond);
        if(e) die("remaining signaling in thread");
      }
      e = pthread_mutex_unlock(&pc->remutex); 
      if(e) die("remaining unlocking in thread");
    }    
  }
  if(g.verbose>1)  printf("Thread terminated. %d merges processed\n",tot);
  pthread_exit(NULL); 
}

// Assembly:
subq $0x5148, %rsp           # imm = 0x5148
movq %rdi, 0x5140(%rsp)
movq 0x5140(%rsp), %rax
movq %rax, 0x5138(%rsp)
movq 0x5138(%rsp), %rax
movq 0x40(%rax), %rax
movq %rax, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movq 0x5138(%rsp), %rax
movq 0x38(%rax), %rdi
callq 0x2070
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x13160
leaq 0x3363(%rip), %rdi      # 0x164be
callq 0x3ce0
movq 0x5138(%rsp), %rdi
addq $0x8, %rdi
callq 0x23e0
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x13188
leaq 0x3349(%rip), %rdi      # 0x164cc
callq 0x3ce0
movq 0x10(%rsp), %rsi
movq 0x5138(%rsp), %rcx
movl 0x4(%rcx), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x4(%rcx)
movq 0x5138(%rsp), %rcx
cltd
idivl 0x48(%rcx)
movslq %edx, %rax
imulq $0x5120, %rax, %rax     # imm = 0x5120
addq %rax, %rsi
leaq 0x18(%rsp), %rdi
movl $0x5120, %edx           # imm = 0x5120
callq 0x21e0
movq 0x5138(%rsp), %rdi
addq $0x8, %rdi
callq 0x2230
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x131f0
leaq 0x32ef(%rip), %rdi      # 0x164da
callq 0x3ce0
movq 0x5138(%rsp), %rax
movq 0x30(%rax), %rdi
callq 0x2160
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x13218
leaq 0x32d7(%rip), %rdi      # 0x164ea
callq 0x3ce0
cmpl $0x0, 0x38(%rsp)
jne 0x13224
jmp 0x133aa
cmpl $0x2, 0xac(%rsp)
jle 0x1324f
movq 0x48(%rsp), %rsi
movq 0x48(%rsp), %rdx
addq 0x40(%rsp), %rdx
subq $0x1, %rdx
leaq 0x32b0(%rip), %rdi      # 0x164f8
movb $0x0, %al
callq 0x20f0
movq 0x5138(%rsp), %rax
testb $0x1, 0xa8(%rax)
je 0x1326e
leaq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0x11a30
jmp 0x1327a
leaq 0x18(%rsp), %rdi
xorl %esi, %esi
callq 0xec00
movl $0x1, 0x4(%rsp)
movl 0x4(%rsp), %eax
cmpl 0x38(%rsp), %eax
jge 0x13308
movq 0x20(%rsp), %rax
movslq 0x4(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
movq 0x20(%rsp), %rax
addq (%rax), %rcx
movq %rcx, (%rax)
testb $0x1, 0x80(%rsp)
je 0x132f6
movl $0x0, (%rsp)
movl (%rsp), %eax
cmpl 0x50(%rsp), %eax
jge 0x132f4
movq 0x30(%rsp), %rax
movslq 0x4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq (%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movq 0x30(%rsp), %rax
movq (%rax), %rax
movslq (%rsp), %rcx
addq (%rax,%rcx,8), %rdx
movq %rdx, (%rax,%rcx,8)
movl (%rsp), %eax
addl $0x1, %eax
movl %eax, (%rsp)
jmp 0x132b6
jmp 0x132f6
jmp 0x132f8
movl 0x4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4(%rsp)
jmp 0x13282
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
movq 0x5138(%rsp), %rdi
addq $0x50, %rdi
callq 0x23e0
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x1333b
leaq 0x31de(%rip), %rdi      # 0x16514
callq 0x3ce0
movq 0x5138(%rsp), %rcx
movl 0x4c(%rcx), %eax
addl $-0x1, %eax
movl %eax, 0x4c(%rcx)
cmpl $0x0, %eax
jne 0x1337b
movq 0x5138(%rsp), %rdi
addq $0x78, %rdi
callq 0x21a0
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x13379
leaq 0x31bc(%rip), %rdi      # 0x16530
callq 0x3ce0
jmp 0x1337b
movq 0x5138(%rsp), %rdi
addq $0x50, %rdi
callq 0x2230
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
je 0x133a3
leaq 0x31b0(%rip), %rdi      # 0x1654e
callq 0x3ce0
jmp 0x133a5
jmp 0x13138
cmpl $0x1, 0xac(%rsp)
jle 0x133c6
movl 0xc(%rsp), %esi
leaq 0x31ad(%rip), %rdi      # 0x1656c
movb $0x0, %al
callq 0x20f0
xorl %eax, %eax
movl %eax, %edi
callq 0x2240
nop