// File: /workspace/github_cpp_makefile_star2_O1/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 0x86f571(%rip), %r14    # 0x87c978
leaq 0x8(%rsp), %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0xd748
leaq 0xbb503(%rip), %rbx     # 0xc8920
movq %r14, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0xa0e0
testb %al, %al
je 0xd6cc
movl 0x144(%rbx), %edx
leaq 0x87936e(%rip), %rdi    # 0x8867b0
leaq 0xbb6a7(%rip), %rsi     # 0xc8af0
callq 0xe980
testb %al, %al
je 0xd6eb
movq 0x10(%rsp), %rsi
leaq 0xbb4be(%rip), %rbx     # 0xc8920
leaq 0xbb687(%rip), %rdx     # 0xc8af0
movq %rbx, %rdi
callq 0x30e3
movq 0x10(%rsp), %rdi
callq 0xe8b3
callq 0xe83b
movl %eax, %r15d
testl %eax, %eax
sete %r12b
je 0xd4b5
leaq 0x1f4c9(%rip), %rdi     # 0x2c95b
xorl %eax, %eax
callq 0x652d
movl %r15d, %edi
callq 0xebc6
xorl %eax, %eax
addq $0x658, %rsp            # imm = 0x658
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x1, 0x86f4a8(%rip)    # 0x87c964
jne 0xd6af
cmpl $0x2, 0x8(%rsp)
jl 0xd6af
xorl %r13d, %r13d
leaq 0x86f669(%rip), %r14    # 0x87cb40
leaq 0x86f49a(%rip), %rbp    # 0x87c978
testb $0x1, %r13b
jne 0xd6af
cmpb $0x0, 0x86f481(%rip)    # 0x87c970
jne 0xd6af
movq %r14, %rdi
callq 0x2290
xorl %r15d, %r15d
leaq 0x1f35b(%rip), %rdi     # 0x2c862
xorl %eax, %eax
callq 0x652d
cmpb $0x0, 0x86f45b(%rip)    # 0x87c970
jne 0xd678
movq 0x18(%rsp), %rax
movq %rax, 0x86f441(%rip)    # 0x87c968
movq 0x86f43a(%rip), %rdi    # 0x87c968
movq %rsp, %r12
movq %r12, %rsi
callq 0xe0f5
movq 0x10(%rsp), %rsi
movq %rbp, %rdi
leaq 0x879268(%rip), %r15    # 0x8867b0
movq %r15, %rdx
callq 0x30e3
movq 0x86f411(%rip), %rsi    # 0x87c968
movq %rbp, %rdi
movq %r15, %rdx
callq 0x30e3
xorl %r15d, %r15d
leaq 0x1f327(%rip), %rdi     # 0x2c893
movq %r12, %rsi
xorl %eax, %eax
callq 0x652d
movb $0x1, 0x86f3e8(%rip)    # 0x87c965
movl $0x1, %edi
callq 0xb2af
xorl %edi, %edi
callq 0xb2be
movq %r14, %rdi
callq 0x20e0
leaq 0x1f30f(%rip), %rdi     # 0x2c8ac
xorl %eax, %eax
callq 0x652d
leaq 0x330(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0xd748
movl $0x328, %edx            # imm = 0x328
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x2100
leaq 0x1f30b(%rip), %rdi     # 0x2c8dd
xorl %eax, %eax
callq 0x652d
movq %r14, %rdi
callq 0x2290
leaq 0x1f311(%rip), %rdi     # 0x2c8f9
xorl %eax, %eax
callq 0x652d
movq $0x0, 0x86f36e(%rip) # 0x87c968
movb $0x1, %r12b
cmpb $0x0, 0x86f361(%rip)    # 0x87c965
jne 0xd667
movq %rbp, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0xa0e0
testb %al, %al
je 0xd70a
movl 0x144(%rbx), %edx
leaq 0x879185(%rip), %rdi    # 0x8867b0
leaq 0xbb4be(%rip), %r15     # 0xc8af0
movq %r15, %rsi
callq 0xe980
testb %al, %al
je 0xd729
movq 0x10(%rsp), %rsi
movq %rbx, %rdi
movq %r15, %rdx
callq 0x30e3
movq 0x10(%rsp), %rdi
callq 0xe8b3
callq 0xe83b
movl %eax, %r15d
movl %r13d, %r12d
movb $0x0, 0x86f2f7(%rip)    # 0x87c965
xorl %edi, %edi
callq 0xb2af
movl %r12d, %r13d
movq %r14, %rdi
callq 0x20e0
leaq 0x1f2a3(%rip), %rdi     # 0x2c92a
xorl %eax, %eax
callq 0x652d
testl %r15d, %r15d
sete %r12b
jne 0xd48b
cmpb $0x1, 0x86f2c2(%rip)    # 0x87c964
jne 0xd6af
cmpl $0x2, 0x8(%rsp)
jge 0xd4de
leaq 0x1f2a5(%rip), %rdi     # 0x2c95b
xorl %eax, %eax
callq 0x652d
testb $0x1, %r12b
je 0xd499
jmp 0xd4a1
leaq 0x1f10b(%rip), %rdi     # 0x2c7de
leaq 0x1f126(%rip), %rsi     # 0x2c800
leaq 0x1f12d(%rip), %rcx     # 0x2c80e
movl $0x57, %edx
callq 0x20d0
leaq 0x1f137(%rip), %rdi     # 0x2c829
leaq 0x1f107(%rip), %rsi     # 0x2c800
leaq 0x1f10e(%rip), %rcx     # 0x2c80e
movl $0x58, %edx
callq 0x20d0
leaq 0x1f0cd(%rip), %rdi     # 0x2c7de
leaq 0x1f0e8(%rip), %rsi     # 0x2c800
leaq 0x1f0ef(%rip), %rcx     # 0x2c80e
movl $0x81, %edx
callq 0x20d0
leaq 0x1f0f9(%rip), %rdi     # 0x2c829
leaq 0x1f0c9(%rip), %rsi     # 0x2c800
leaq 0x1f0d0(%rip), %rcx     # 0x2c80e
movl $0x82, %edx
callq 0x20d0