// File: /workspace/github_cpp_makefile_star2_O3/jswaff[P]prophet3/src/think.cpp
// Function: think_helper(void*)
void* think_helper(void *ptr) {

    move_line pv = iterate(&search_pos,false);

    // sanity check - the global position shouldn't have changed
    assert(equal_pos(&search_pos,&gpos,true));
    assert(undo_stacks_equal(search_undos,gundos,gpos.move_counter));

    apply_move(&gpos,pv.mv[0],gundos);
    print_move(pv.mv[0]);
    game_status gs = get_game_status();


    // pondering loop.  as long as we guess correctly we'll loop back around.
    // if we don't predict correctly this thread is terminated.
    bool ponder_failure = false;
    char move_buffer[8];
    while (gs==INPROGRESS && pondering_enabled && pv.n > 1 && !ponder_failure && !abort_iterator) {

        pthread_mutex_lock(&ponder_mutex);
        printd("# think_helper acquired lock #1 on ponder_mutex\n");

        if (!abort_iterator) {
            ponder_move = pv.mv[1];
            move_to_str(ponder_move,move_buffer);
            apply_move(&search_pos,pv.mv[0],search_undos); // apply the move just made so we're in sync
            apply_move(&search_pos,ponder_move,search_undos); // apply the predicted move

            printd("### START PONDERING: %s\n",move_buffer);

            set_ponder_mode(true);
            set_abort_search(false);

            pthread_mutex_unlock(&ponder_mutex);
            printd("# think_helper released lock #1 on ponder_mutex\n");

            pv = iterate(&search_pos,false);
            printd("# ponder search terminated\n");

            pthread_mutex_lock(&ponder_mutex);
            printd("# think_helper acquired lock #2 on ponder_mutex\n");

            ponder_move = 0;

            // if we're not in ponder mode, it's because the usermove was correctly predicted and the main
            // thread transitioned the search into "normal mode."
            if (!pondering) {
                assert(equal_pos(&search_pos,&gpos,true));
                assert(undo_stacks_equal(search_undos,gundos,gpos.move_counter));
                apply_move(&gpos,pv.mv[0],gundos);
                print_move(pv.mv[0]);
                gs = get_game_status();
            } else {
                // we're still in ponder mode.  this means the search terminated on its own.
                // in this case just bail out.
                ponder_failure = true;
            }

            set_ponder_mode(false);
        }

        pthread_mutex_unlock(&ponder_mutex);
        printd("# think_helper released lock #2 on ponder_mutex\n");

    }

    // If game is over by rule then print the result
    printd("# exiting search thread\n");

    if (gs != INPROGRESS) {
        print_result(gs);
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x658, %rsp            # imm = 0x658
leaq 0x86f581(%rip), %r14    # 0x87c978
leaq 0x8(%rsp), %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0xd713
leaq 0xbb513(%rip), %rbx     # 0xc8920
movq %r14, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0xa0b8
testb %al, %al
je 0xd697
movl 0x144(%rbx), %edx
leaq 0x87937e(%rip), %rdi    # 0x8867b0
leaq 0xbb6b7(%rip), %rsi     # 0xc8af0
callq 0xe8d8
testb %al, %al
je 0xd6b6
movq 0x10(%rsp), %rsi
leaq 0xbb4ce(%rip), %rbx     # 0xc8920
leaq 0xbb697(%rip), %rdx     # 0xc8af0
movq %rbx, %rdi
callq 0x30e1
movq 0x10(%rsp), %rdi
callq 0xe7f9
callq 0xe781
movl %eax, %r13d
testl %eax, %eax
je 0xd492
leaq 0x1f55d(%rip), %rdi     # 0x2c9db
xorl %eax, %eax
callq 0x65d9
movl %r13d, %edi
callq 0xeb12
jmp 0xd683
xorl %r12d, %r12d
leaq 0x86f6a4(%rip), %r14    # 0x87cb40
leaq 0x86f4d5(%rip), %rbp    # 0x87c978
leaq 0x879306(%rip), %r15    # 0x8867b0
cmpb $0x1, 0x86f4b3(%rip)    # 0x87c964
jne 0xd675
cmpl $0x2, 0x8(%rsp)
jl 0xd675
testb $0x1, %r12b
jne 0xd675
cmpb $0x0, 0x86f49d(%rip)    # 0x87c970
jne 0xd675
movq %r14, %rdi
callq 0x2290
xorl %r13d, %r13d
leaq 0x1f3f7(%rip), %rdi     # 0x2c8e2
xorl %eax, %eax
callq 0x65d9
cmpb $0x0, 0x86f477(%rip)    # 0x87c970
movl $0x0, %r12d
jne 0xd651
movq 0x18(%rsp), %rax
movq %rax, 0x86f457(%rip)    # 0x87c968
movq 0x86f450(%rip), %rdi    # 0x87c968
movq %rsp, %r12
movq %r12, %rsi
callq 0xe09f
movq 0x10(%rsp), %rsi
movq %rbp, %rdi
movq %r15, %rdx
callq 0x30e1
movq 0x86f42e(%rip), %rsi    # 0x87c968
movq %rbp, %rdi
movq %r15, %rdx
callq 0x30e1
xorl %r13d, %r13d
leaq 0x1f3c4(%rip), %rdi     # 0x2c913
movq %r12, %rsi
xorl %eax, %eax
callq 0x65d9
movb $0x1, 0x86f405(%rip)    # 0x87c965
movl $0x1, %edi
callq 0xb2ab
xorl %edi, %edi
callq 0xb2ba
movq %r14, %rdi
callq 0x20e0
leaq 0x1f3ac(%rip), %rdi     # 0x2c92c
xorl %eax, %eax
callq 0x65d9
leaq 0x330(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0xd713
movl $0x328, %edx            # imm = 0x328
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x2100
leaq 0x1f3a8(%rip), %rdi     # 0x2c95d
xorl %eax, %eax
callq 0x65d9
movq %r14, %rdi
callq 0x2290
leaq 0x1f3ae(%rip), %rdi     # 0x2c979
xorl %eax, %eax
callq 0x65d9
movq $0x0, 0x86f38b(%rip) # 0x87c968
movb 0x86f381(%rip), %r12b   # 0x87c965
testb %r12b, %r12b
jne 0xd643
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0xa0b8
testb %al, %al
je 0xd6d5
movl 0x144(%rbx), %edx
movq %r15, %rdi
leaq 0xbb4df(%rip), %r13     # 0xc8af0
movq %r13, %rsi
callq 0xe8d8
testb %al, %al
je 0xd6f4
movq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r13, %rdx
callq 0x30e1
movq 0x10(%rsp), %rdi
callq 0xe7f9
callq 0xe781
movl %eax, %r13d
movb $0x0, 0x86f31b(%rip)    # 0x87c965
xorl %edi, %edi
callq 0xb2ab
movq %r14, %rdi
callq 0x20e0
leaq 0x1f34a(%rip), %rdi     # 0x2c9aa
xorl %eax, %eax
callq 0x65d9
testl %r13d, %r13d
je 0xd4aa
jmp 0xd477
leaq 0x1f35f(%rip), %rdi     # 0x2c9db
xorl %eax, %eax
callq 0x65d9
xorl %eax, %eax
addq $0x658, %rsp            # imm = 0x658
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1f1c0(%rip), %rdi     # 0x2c85e
leaq 0x1f1db(%rip), %rsi     # 0x2c880
leaq 0x1f1e2(%rip), %rcx     # 0x2c88e
movl $0x57, %edx
callq 0x20d0
leaq 0x1f1ec(%rip), %rdi     # 0x2c8a9
leaq 0x1f1bc(%rip), %rsi     # 0x2c880
leaq 0x1f1c3(%rip), %rcx     # 0x2c88e
movl $0x58, %edx
callq 0x20d0
leaq 0x1f182(%rip), %rdi     # 0x2c85e
leaq 0x1f19d(%rip), %rsi     # 0x2c880
leaq 0x1f1a4(%rip), %rcx     # 0x2c88e
movl $0x81, %edx
callq 0x20d0
leaq 0x1f1ae(%rip), %rdi     # 0x2c8a9
leaq 0x1f17e(%rip), %rsi     # 0x2c880
leaq 0x1f185(%rip), %rcx     # 0x2c88e
movl $0x82, %edx
callq 0x20d0