// File: /workspace/github_cpp_makefile_star2_O3/kobanium[P]Ray/src/mcts/UctSearch.cpp
// Function: ParallelUctSearch(thread_arg_t*)
static void
ParallelUctSearch( thread_arg_t *arg )
{
  const thread_arg_t *targ = (thread_arg_t *)arg;
  const int color = targ->color;
  bool interruption = false, enough_size = true;
  bool use_analysis = targ->lz_analysis_cs > 0 ? true : false;
  int winner = 0, interval = CRITICALITY_INTERVAL;
  game_info_t *game = AllocateGame();
  ray_clock::time_point analysis_timer;

  // スレッドIDが0のスレッドだけ別の処理をする
  // 探索回数が閾値を超える, または探索が打ち切られたらループを抜ける
  if (targ->thread_id == 0) {
    analysis_timer = ray_clock::now();

    do {
      // 探索回数を1回増やす
      IncrementPoCount();
      // 盤面のコピー
      CopyGame(game, targ->game);
      // 1回プレイアウトする
      UctSearch(game, color, mt[targ->thread_id], current_root, winner);
      // 探索を打ち切るか確認
      interruption = CheckInterruption(uct_node[current_root]);
      //interruption = InterruptionCheck();
      // ハッシュに余裕があるか確認
      enough_size = CheckRemainingHashSize();
      // OwnerとCriticalityを計算する
      if (GetPoCount() > interval) {
        CalculateOwner(color);
        CalculateCriticality(color);
        interval += CRITICALITY_INTERVAL;
      }

      if (use_analysis &&
          static_cast<int>(100 * GetSpendTime(analysis_timer)) > targ->lz_analysis_cs) {
        analysis_timer = ray_clock::now();
        PrintLeelaZeroAnalyze(&uct_node[current_root]);
      }

      if (IsTimeOver()) break;
    } while (IsSearchContinue() && !interruption && enough_size);
  } else {
    do {
      // 探索回数を1回増やす
      IncrementPoCount();
      // 盤面のコピー
      CopyGame(game, targ->game);
      // 1回プレイアウトする
      UctSearch(game, color, mt[targ->thread_id], current_root, winner);
      // 探索を打ち切るか確認
      interruption = CheckInterruption(uct_node[current_root]);
      //interruption = InterruptionCheck();
      // ハッシュに余裕があるか確認
      enough_size = CheckRemainingHashSize();

      if (IsTimeOver()) break;
    } while (IsSearchContinue() && !interruption && enough_size);
  }

  // メモリの解放
  FreeGame(game);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl 0xc(%rdi), %ebp
movl 0x10(%rdi), %r15d
callq 0x543a6
movq %rax, %r14
cmpl $0x0, 0x8(%rbx)
je 0x4b214
leaq 0xc(%rsp), %r15
callq 0x4d90d
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x549d9
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa9078e(%rip), %rax  # 0x1aadb940
addq %rax, %rdx
movl 0x1aa9077d(%rip), %ecx  # 0x1aadb938
movq %r14, %rdi
movl %ebp, %esi
movq %r15, %r8
callq 0x4c10f
movslq 0x1aa90769(%rip), %rax  # 0x1aadb938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa90753(%rip), %rdi  # 0x1aadb930
callq 0x4d915
movl %eax, %r12d
callq 0x56cc4
movl %eax, %r13d
callq 0x4d887
testb %al, %al
jne 0x4b333
callq 0x4d8c9
andb %al, %r13b
xorb $0x1, %r13b
orb %r13b, %r12b
cmpb $0x1, %r12b
jne 0x4b190
jmp 0x4b333
movl %r15d, 0x8(%rsp)
movl $0x64, %r12d
callq 0x6070
movq %rax, 0x10(%rsp)
callq 0x4d90d
movq (%rbx), %rsi
movq %r14, %rdi
callq 0x549d9
movslq 0x8(%rbx), %rax
imulq $0x9c8, %rax, %rdx      # imm = 0x9C8
leaq 0x1aa906f5(%rip), %rax  # 0x1aadb940
addq %rax, %rdx
movl 0x1aa906e4(%rip), %ecx  # 0x1aadb938
movq %r14, %rdi
movl %ebp, %esi
leaq 0xc(%rsp), %r8
callq 0x4c10f
movslq 0x1aa906ce(%rip), %rax  # 0x1aadb938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa906b8(%rip), %rdi  # 0x1aadb930
callq 0x4d915
movl %eax, %r13d
callq 0x56cc4
movl %eax, %r15d
callq 0x4d8e2
cmpl %r12d, %eax
jle 0x4b2a4
movl %ebp, %edi
callq 0x4c6d5
movl %ebp, %edi
callq 0x4c789
addl $0x64, %r12d
cmpl $0x0, 0x8(%rsp)
jle 0x4b315
callq 0x6070
subq 0x10(%rsp), %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rax
shrq $0x3f, %rax
sarq $0x12, %rdx
addq %rax, %rdx
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
divsd 0x14d60(%rip), %xmm0    # 0x60040
mulsd 0x11d30(%rip), %xmm0    # 0x5d018
cvttsd2si %xmm0, %eax
cmpl %eax, 0x10(%rbx)
jge 0x4b315
callq 0x6070
movq %rax, 0x10(%rsp)
movslq 0x1aa90636(%rip), %rax  # 0x1aadb938
imulq $0x4548, %rax, %rdi     # imm = 0x4548
addq 0x1aa90620(%rip), %rdi  # 0x1aadb930
callq 0x1edc6
callq 0x4d887
testb %al, %al
jne 0x4b333
callq 0x4d8c9
andb %al, %r15b
xorb $0x1, %r15b
orb %r15b, %r13b
je 0x4b229
movq %r14, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x543c1