// File: /workspace/github_c_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x5128, %rsp           # imm = 0x5128
movq %rdi, %rbx
movq 0x40(%rdi), %r12
leaq 0x8(%rdi), %r14
leaq 0x50(%rdi), %r15
leaq 0x78(%rdi), %rax
movq %rax, (%rsp)
leaq 0x8(%rsp), %r13
xorl %ebp, %ebp
movq 0x38(%rbx), %rdi
callq 0x2080
testl %eax, %eax
je 0xc221
leaq 0x3278(%rip), %rdi      # 0xf494
callq 0x35b7
movq %r14, %rdi
callq 0x23f0
testl %eax, %eax
je 0xc239
leaq 0x326e(%rip), %rdi      # 0xf4a2
callq 0x35b7
movl 0x4(%rbx), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x4(%rbx)
cltd
idivl 0x48(%rbx)
movslq %edx, %rax
imulq $0x5120, %rax, %rsi     # imm = 0x5120
addq %r12, %rsi
movl $0x5120, %edx           # imm = 0x5120
movq %r13, %rdi
callq 0x21f0
movq %r14, %rdi
callq 0x2240
testl %eax, %eax
je 0xc278
leaq 0x323d(%rip), %rdi      # 0xf4b0
callq 0x35b7
movq 0x30(%rbx), %rdi
callq 0x2170
testl %eax, %eax
je 0xc291
leaq 0x3234(%rip), %rdi      # 0xf4c0
callq 0x35b7
cmpl $0x0, 0x28(%rsp)
movl 0x9c(%rsp), %eax
je 0xc395
cmpl $0x3, %eax
jl 0xc2c7
movq 0x30(%rsp), %rax
movq 0x38(%rsp), %rsi
leaq (%rsi,%rax), %rdx
decq %rdx
leaq 0x320e(%rip), %rdi      # 0xf4ce
xorl %eax, %eax
callq 0x2100
cmpb $0x1, 0xa8(%rbx)
jne 0xc2dc
movq %r13, %rdi
xorl %esi, %esi
callq 0xb558
jmp 0xc2e6
movq %r13, %rdi
xorl %esi, %esi
callq 0x9e9e
movslq 0x28(%rsp), %rax
movq 0x10(%rsp), %rcx
movb 0x70(%rsp), %dl
movl 0x40(%rsp), %esi
testl %esi, %esi
movl $0x0, %edi
cmovlel %edi, %esi
pushq $0x1
popq %rdi
cmpq %rax, %rdi
jge 0xc33c
movq (%rcx,%rdi,8), %r8
addq %r8, (%rcx)
testb $0x1, %dl
je 0xc337
movq 0x20(%rsp), %r8
xorl %r9d, %r9d
cmpq %r9, %rsi
je 0xc337
movq (%r8,%rdi,8), %r10
movq (%r10,%r9,8), %r10
movq (%r8), %r11
addq %r10, (%r11,%r9,8)
incq %r9
jmp 0xc31e
incq %rdi
jmp 0xc305
movq %r15, %rdi
callq 0x23f0
testl %eax, %eax
je 0xc354
leaq 0x319b(%rip), %rdi      # 0xf4ea
callq 0x35b7
decl 0x4c(%rbx)
jne 0xc372
movq (%rsp), %rdi
callq 0x21b0
testl %eax, %eax
je 0xc372
leaq 0x3199(%rip), %rdi      # 0xf506
callq 0x35b7
incl %ebp
movq %r15, %rdi
callq 0x2240
testl %eax, %eax
je 0xc208
leaq 0x3199(%rip), %rdi      # 0xf524
callq 0x35b7
jmp 0xc208
cmpl $0x2, %eax
jl 0xc3aa
leaq 0x31a1(%rip), %rdi      # 0xf542
movl %ebp, %esi
xorl %eax, %eax
callq 0x2100
xorl %edi, %edi
callq 0x2250
nopl (%rax)