// File: /workspace/github_cpp_makefile_star2_O3/sisong[P]ApkDiffPatch/lzma/C/MtCoder.c
// Function: MtCoder_Code
SRes MtCoder_Code(CMtCoder *p)
{
  unsigned numThreads = p->numThreadsMax;
  unsigned numBlocksMax;
  unsigned i;
  SRes res = SZ_OK;

  if (numThreads > MTCODER_THREADS_MAX)
      numThreads = MTCODER_THREADS_MAX;
  numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads);
  
  if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++;
  if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++;
  if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++;

  if (numBlocksMax > MTCODER_BLOCKS_MAX)
      numBlocksMax = MTCODER_BLOCKS_MAX;

  if (p->blockSize != p->allocatedBufsSize)
  {
    for (i = 0; i < MTCODER_THREADS_MAX; i++)
    {
      CMtCoderThread *t = &p->threads[i];
      if (t->inBuf)
      {
        ISzAlloc_Free(p->allocBig, t->inBuf);
        t->inBuf = NULL;
      }
    }
    p->allocatedBufsSize = p->blockSize;
  }

  p->readRes = SZ_OK;

  MtProgress_Init(&p->mtProgress, p->progress);

  #ifdef MTCODER_USE_WRITE_THREAD
    for (i = 0; i < numBlocksMax; i++)
    {
      RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->writeEvents[i]))
    }
  #else
    RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent))
  #endif

  {
    RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->readEvent))
    RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, (UInt32)numBlocksMax, (UInt32)numBlocksMax))
  }

  for (i = 0; i < MTCODER_BLOCKS_MAX - 1; i++)
    p->freeBlockList[i] = i + 1;
  p->freeBlockList[MTCODER_BLOCKS_MAX - 1] = (unsigned)(int)-1;
  p->freeBlockHead = 0;

  p->readProcessed = 0;
  p->blockIndex = 0;
  p->numBlocksMax = numBlocksMax;
  p->stopReading = False;

  #ifndef MTCODER_USE_WRITE_THREAD
    p->writeIndex = 0;
    p->writeRes = SZ_OK;
    for (i = 0; i < MTCODER_BLOCKS_MAX; i++)
      p->ReadyBlocks[i] = False;
    p->numFinishedThreads = 0;
  #endif

  p->numStartedThreadsLimit = numThreads;
  p->numStartedThreads = 0;

  // for (i = 0; i < numThreads; i++)
  {
    CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++];
    RINOK(MtCoderThread_CreateAndStart(nextThread))
  }

  RINOK_THREAD(Event_Set(&p->readEvent))

  #ifdef MTCODER_USE_WRITE_THREAD
  {
    unsigned bi = 0;

    for (;; bi++)
    {
      if (bi >= numBlocksMax)
        bi = 0;

      RINOK_THREAD(Event_Wait(&p->writeEvents[bi]))

      {
        const CMtCoderBlock *block = &p->blocks[bi];
        unsigned bufIndex = block->bufIndex;
        BoolInt finished = block->finished;
        if (res == SZ_OK && block->res != SZ_OK)
          res = block->res;

        if (bufIndex != (unsigned)(int)-1)
        {
          if (res == SZ_OK)
          {
            res = p->mtCallback->Write(p->mtCallbackObject, bufIndex);
            if (res != SZ_OK)
              MtProgress_SetError(&p->mtProgress, res);
          }
          
          CriticalSection_Enter(&p->cs);
          {
            p->freeBlockList[bufIndex] = p->freeBlockHead;
            p->freeBlockHead = bufIndex;
          }
          CriticalSection_Leave(&p->cs);
        }
        
        RINOK_THREAD(Semaphore_Release1(&p->blocksSemaphore))

        if (finished)
          break;
      }
    }
  }
  #else
  {
    WRes wres = Event_Wait(&p->finishedEvent);
    res = MY_SRes_HRESULT_FROM_WRes(wres);
  }
  #endif

  if (res == SZ_OK)
    res = p->readRes;

  if (res == SZ_OK)
    res = p->mtProgress.res;

  #ifndef MTCODER_USE_WRITE_THREAD
    if (res == SZ_OK)
      res = p->writeRes;
  #endif

  if (res != SZ_OK)
    MtCoder_Free(p);
  return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x8(%rdi), %eax
cmpl $0x40, %eax
movl $0x40, %r13d
cmovbl %eax, %r13d
movl %r13d, %eax
shrl $0x3, %eax
movq (%rdi), %rcx
cmpq $0x4000000, %rcx        # imm = 0x4000000
adcl %r13d, %eax
xorl %ebp, %ebp
cmpq $0x1000000, %rcx        # imm = 0x1000000
setb %bpl
cmpq $0x400000, %rcx         # imm = 0x400000
adcl %eax, %ebp
cmpq 0x50(%rdi), %rcx
je 0x3b7ef
movl $0x750, %r14d           # imm = 0x750
movq (%rbx,%r14), %rsi
testq %rsi, %rsi
je 0x3b7d8
movq 0x38(%rbx), %rdi
callq *0x8(%rdi)
movq $0x0, (%rbx,%r14)
addq $0x90, %r14
cmpq $0x2b50, %r14           # imm = 0x2B50
jne 0x3b7c0
movq (%rbx), %rax
movq %rax, 0x50(%rbx)
movl $0x0, 0x12c(%rbx)
leaq 0x368(%rbx), %rdi
movq 0x30(%rbx), %rsi
callq 0x3bfc8
leaq 0x130(%rbx), %r14
movq %r14, %rdi
callq 0x3da6a
movl $0xc, %r12d
testl %eax, %eax
jne 0x3b9be
leaq 0x58(%rbx), %r15
movq %r15, %rdi
callq 0x3da6a
testl %eax, %eax
jne 0x3b9be
incl %ebp
leaq 0xc0(%rbx), %rdi
movl %ebp, %esi
movl %ebp, %edx
callq 0x3d911
testl %eax, %eax
jne 0x3b9be
movdqa 0x24154(%rip), %xmm0    # 0x5f9b0
movl $0x8e, %eax
movdqa 0x24157(%rip), %xmm1    # 0x5f9c0
movdqa 0x241af(%rip), %xmm2    # 0x5fa20
pshufd $0xf5, %xmm2, %xmm3     # xmm3 = xmm2[1,1,3,3]
pcmpeqd %xmm4, %xmm4
movdqa 0x241ae(%rip), %xmm5    # 0x5fa30
movdqa %xmm0, %xmm6
pxor %xmm1, %xmm6
movdqa %xmm2, %xmm8
pcmpgtd %xmm6, %xmm8
pshufd $0xf5, %xmm6, %xmm7     # xmm7 = xmm6[1,1,3,3]
pcmpeqd %xmm3, %xmm7
pand %xmm8, %xmm7
movdqa %xmm0, %xmm6
psubq %xmm4, %xmm6
movd %xmm7, %ecx
testb $0x1, %cl
je 0x3b8b9
movd %xmm6, -0x4(%rbx,%rax,4)
pextrw $0x4, %xmm7, %ecx
testb $0x1, %cl
je 0x3b8cd
pshufd $0xee, %xmm6, %xmm6     # xmm6 = xmm6[2,3,2,3]
movd %xmm6, (%rbx,%rax,4)
paddq %xmm5, %xmm0
addq $0x2, %rax
cmpq $0xda, %rax
jne 0x3b882
movl $0xffffffff, 0x360(%rbx) # imm = 0xFFFFFFFF
xorl %eax, %eax
movl %eax, 0x230(%rbx)
movq %rax, 0x200(%rbx)
movl %eax, 0x1fc(%rbx)
movl %ebp, 0x1f8(%rbx)
movl %eax, 0x128(%rbx)
pxor %xmm0, %xmm0
movdqu %xmm0, 0x198(%rbx)
movdqu %xmm0, 0x1a8(%rbx)
movdqu %xmm0, 0x1b8(%rbx)
movdqu %xmm0, 0x1c8(%rbx)
movdqu %xmm0, 0x1d8(%rbx)
movq %rax, 0x1e8(%rbx)
movl %r13d, 0x1f0(%rbx)
leaq 0x740(%rbx), %rdi
movl $0x1, 0x1f4(%rbx)
callq 0x3b9d5
movl %eax, %r12d
testl %eax, %eax
jne 0x3b9be
movq %r15, %rdi
callq 0x3d7a5
movl $0xc, %r12d
testl %eax, %eax
jne 0x3b9be
movq %r14, %rdi
callq 0x3d81e
movzwl %ax, %r12d
orl $0x88000000, %r12d      # imm = 0x88000000
testl %eax, %eax
cmovlel %eax, %r12d
testl %r12d, %r12d
jne 0x3b9b6
movl 0x12c(%rbx), %r12d
testl %r12d, %r12d
jne 0x3b9b6
movl 0x370(%rbx), %r12d
testl %r12d, %r12d
jne 0x3b9b6
leaq 0x198(%rbx), %rax
movl (%rax), %r12d
testl %r12d, %r12d
je 0x3b9d0
movq %rbx, %rdi
callq 0x3b6b6
movl %r12d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r12d, %r12d
jmp 0x3b9be