// File: sisong[P]ApkDiffPatch/lzma/C/LzFindMt.c
// Function: HashThreadFunc
static void HashThreadFunc(CMatchFinderMt *mt)
{
  CMtSync *p = &mt->hashSync;
    PRF(printf("\nHashThreadFunc\n"));
  
  for (;;)
  {
    UInt32 blockIndex = 0;
      PRF(printf("\nHashThreadFunc : Event_Wait(&p->canStart)\n"));
    Event_Wait(&p->canStart);
      PRF(printf("\nHashThreadFunc : Event_Wait(&p->canStart) : after \n"));
    if (p->exit)
    {
      PRF(printf("\nHashThreadFunc : exit \n"));
      return;
    }

    MatchFinder_Init_HighHash(MF(mt));

    for (;;)
    {
      PRF(printf("Hash thread block = %d pos = %d\n", (unsigned)blockIndex, mt->MatchFinder->pos));

      {
        CMatchFinder *mf = MF(mt);
        if (MatchFinder_NeedMove(mf))
        {
          CriticalSection_Enter(&mt->btSync.cs);
          CriticalSection_Enter(&mt->hashSync.cs);
          {
            const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
            ptrdiff_t offset;
            MatchFinder_MoveBlock(mf);
            offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
            mt->pointerToCurPos -= offset;
            mt->buffer -= offset;
          }
          CriticalSection_Leave(&mt->hashSync.cs);
          CriticalSection_Leave(&mt->btSync.cs);
          continue;
        }

        Semaphore_Wait(&p->freeSemaphore);

        if (p->exit) // exit is unexpected here. But we check it here for some failure case
          return;

        // for faster stop : we check (p->stopWriting) after Wait(freeSemaphore)
        if (p->stopWriting)
          break;

        MatchFinder_ReadIfRequired(mf);
        {
          UInt32 *heads = mt->hashBuf + GET_HASH_BLOCK_OFFSET(blockIndex++);
          UInt32 num = Inline_MatchFinder_GetNumAvailableBytes(mf);
          heads[0] = 2;
          heads[1] = num;

          /* heads[1] contains the number of avail bytes:
             if (avail < mf->numHashBytes) :
             {
               it means that stream was finished
               HASH_THREAD and BT_TREAD must move position for heads[1] (avail) bytes.
               HASH_THREAD doesn't stop,
               HASH_THREAD fills only the header (2 numbers) for all next blocks:
               {2, NumHashBytes - 1}, {2,0}, {2,0}, ... , {2,0}
             }
             else
             {
               HASH_THREAD and BT_TREAD must move position for (heads[0] - 2) bytes;
             }
          */

          if (num >= mf->numHashBytes)
          {
            num = num - mf->numHashBytes + 1;
            if (num > kMtHashBlockSize - 2)
              num = kMtHashBlockSize - 2;

            if (mf->pos > (UInt32)kMtMaxValForNormalize - num)
            {
              const UInt32 subValue = (mf->pos - mf->historySize - 1); // & ~(UInt32)(kNormalizeAlign - 1);
              MatchFinder_REDUCE_OFFSETS(mf, subValue)
              MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1);
            }

            heads[0] = 2 + num;
            mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
          }

          mf->pos += num;  // wrap over zero is allowed at the end of stream
          mf->buffer += num;
        }
      }

      Semaphore_Release1(&p->filledSemaphore);
    } // for() processing end

    // p->numBlocks_Sent = blockIndex;
    Event_Set(&p->wasStopped);
  } // for() thread end
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x318, %rax            # imm = 0x318
movq %rax, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x10(%rbp), %rdi
addq $0x38, %rdi
callq 0x7b6d0
movq -0x10(%rbp), %rax
cmpl $0x0, 0x30(%rax)
je 0x76f2d
jmp 0x771e2
movq -0x8(%rbp), %rax
movq 0x520(%rax), %rdi
callq 0x6fbf0
movq -0x8(%rbp), %rax
movq 0x520(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6f0b0
cmpl $0x0, %eax
je 0x77013
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
callq 0x7bab0
movq -0x8(%rbp), %rdi
addq $0x318, %rdi            # imm = 0x318
addq $0x1d8, %rdi            # imm = 0x1D8
callq 0x7bab0
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
callq 0x6f010
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rcx
xorl %edx, %edx
subq %rsi, %rdx
addq %rdx, %rcx
movq %rcx, (%rax)
movq -0x30(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x300(%rax), %rcx
xorl %edx, %edx
subq %rsi, %rdx
addq %rdx, %rcx
movq %rcx, 0x300(%rax)
movq -0x8(%rbp), %rdi
addq $0x318, %rdi            # imm = 0x318
addq $0x1d8, %rdi            # imm = 0x1D8
callq 0x7bae0
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
addq $0x1d8, %rdi            # imm = 0x1D8
callq 0x7bae0
jmp 0x76f3d
movq -0x10(%rbp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x7b980
movq -0x10(%rbp), %rax
cmpl $0x0, 0x30(%rax)
je 0x77032
jmp 0x771e2
movq -0x10(%rbp), %rax
cmpl $0x0, 0x34(%rax)
je 0x77041
jmp 0x771cd
movq -0x20(%rbp), %rdi
callq 0x6f130
movq -0x8(%rbp), %rax
movq 0x2d0(%rax), %rax
movl -0x14(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x14(%rbp)
andl $0x1, %ecx
shll $0x11, %ecx
movl %ecx, %ecx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x20(%rbp), %rax
movl 0x10(%rax), %eax
movq -0x20(%rbp), %rcx
subl 0x8(%rcx), %eax
movl %eax, -0x3c(%rbp)
movq -0x38(%rbp), %rax
movl $0x2, (%rax)
movl -0x3c(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0x4(%rax)
movl -0x3c(%rbp), %eax
movq -0x20(%rbp), %rcx
cmpl 0x5c(%rcx), %eax
jb 0x77194
movl -0x3c(%rbp), %eax
movq -0x20(%rbp), %rcx
subl 0x5c(%rcx), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
cmpl $0x1fffe, -0x3c(%rbp)   # imm = 0x1FFFE
jbe 0x770c8
movl $0x1fffe, -0x3c(%rbp)   # imm = 0x1FFFE
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
subl -0x3c(%rbp), %ecx
cmpl %ecx, %eax
jbe 0x77138
movq -0x20(%rbp), %rax
movl 0x8(%rax), %eax
movq -0x20(%rbp), %rcx
subl 0x68(%rcx), %eax
subl $0x1, %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %edx
movq -0x20(%rbp), %rax
movl 0x8(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x8(%rax)
movl -0x40(%rbp), %edx
movq -0x20(%rbp), %rax
movl 0x10(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x10(%rax)
movl -0x40(%rbp), %edi
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rsi
movq -0x20(%rbp), %rax
movl 0x6c(%rax), %eax
shlq $0x2, %rax
addq %rax, %rsi
movq -0x20(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, %edx
addq $0x1, %rdx
callq 0x6fdf0
movl -0x3c(%rbp), %ecx
addl $0x2, %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rax
movq 0x518(%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rdi
movq -0x20(%rbp), %rcx
movl 0x8(%rcx), %esi
movq -0x20(%rbp), %rcx
movq 0x28(%rcx), %rdx
movq -0x20(%rbp), %rcx
movl 0x6c(%rcx), %ecx
shlq $0x2, %rcx
addq %rcx, %rdx
movq -0x20(%rbp), %rcx
movl 0x38(%rcx), %ecx
movq -0x38(%rbp), %r8
addq $0x8, %r8
movl -0x3c(%rbp), %r9d
movq -0x20(%rbp), %r10
addq $0x78, %r10
movq %r10, (%rsp)
callq *%rax
movl -0x3c(%rbp), %ecx
movq -0x20(%rbp), %rax
addl 0x8(%rax), %ecx
movl %ecx, 0x8(%rax)
movl -0x3c(%rbp), %edx
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movl %edx, %edx
addq %rdx, %rcx
movq %rcx, (%rax)
movq -0x10(%rbp), %rdi
addq $0x170, %rdi            # imm = 0x170
movl $0x1, %esi
callq 0x7b8d0
jmp 0x76f3d
movq -0x10(%rbp), %rdi
addq $0xa0, %rdi
callq 0x7b600
jmp 0x76f0a
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)