// File: 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
movq %rsp, %rbp
subq $0x670, %rsp            # imm = 0x670
movq %rdi, -0x8(%rbp)
leaq -0x330(%rbp), %rdi
leaq 0x87494b(%rip), %rsi    # 0x887b38
xorl %edx, %edx
callq 0x13560
leaq 0x87493d(%rip), %rdi    # 0x887b38
leaq 0xc08de(%rip), %rsi     # 0xd3ae0
movl $0x1, %edx
callq 0xe490
testb $0x1, %al
jne 0x13212
jmp 0x13214
jmp 0x13233
leaq 0x25583(%rip), %rdi     # 0x3879e
leaq 0x2559e(%rip), %rsi     # 0x387c0
movl $0x57, %edx
leaq 0x255a0(%rip), %rcx     # 0x387ce
callq 0x20c0
leaq 0xc08a6(%rip), %rax     # 0xd3ae0
movl 0x144(%rax), %edx
leaq 0x87e729(%rip), %rdi    # 0x891970
leaq 0xc0a62(%rip), %rsi     # 0xd3cb0
callq 0x15020
testb $0x1, %al
jne 0x13259
jmp 0x1325b
jmp 0x1327a
leaq 0x25587(%rip), %rdi     # 0x387e9
leaq 0x25557(%rip), %rsi     # 0x387c0
movl $0x58, %edx
leaq 0x25559(%rip), %rcx     # 0x387ce
callq 0x20c0
movq -0x328(%rbp), %rsi
leaq 0xc0858(%rip), %rdi     # 0xd3ae0
leaq 0xc0a21(%rip), %rdx     # 0xd3cb0
callq 0x3620
movq -0x328(%rbp), %rdi
callq 0x14ed0
callq 0x14e20
movl %eax, -0x334(%rbp)
movb $0x0, -0x335(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x334(%rbp)
movb %al, -0x669(%rbp)
jne 0x13304
xorl %eax, %eax
testb $0x1, 0x874858(%rip)    # 0x887b24
movb %al, -0x669(%rbp)
je 0x13304
xorl %eax, %eax
cmpl $0x1, -0x330(%rbp)
movb %al, -0x669(%rbp)
jle 0x13304
xorl %eax, %eax
testb $0x1, -0x335(%rbp)
movb %al, -0x669(%rbp)
jne 0x13304
movb 0x874834(%rip), %al     # 0x887b30
xorb $-0x1, %al
movb %al, -0x669(%rbp)
movb -0x669(%rbp), %al
testb $0x1, %al
jne 0x13313
jmp 0x13524
leaq 0x8749e6(%rip), %rdi    # 0x887d00
callq 0x2290
leaq 0x254fc(%rip), %rdi     # 0x38822
movb $0x0, %al
callq 0x8db0
movb 0x8747fd(%rip), %al     # 0x887b30
testb $0x1, %al
jne 0x13505
movq -0x320(%rbp), %rax
movq %rax, 0x8747df(%rip)    # 0x887b28
movq 0x8747d8(%rip), %rdi    # 0x887b28
leaq -0x33d(%rbp), %rsi
callq 0x14350
movq -0x328(%rbp), %rsi
leaq 0x8747ce(%rip), %rdi    # 0x887b38
leaq 0x87e5ff(%rip), %rdx    # 0x891970
callq 0x3620
movq 0x8747ab(%rip), %rsi    # 0x887b28
leaq 0x8747b4(%rip), %rdi    # 0x887b38
leaq 0x87e5e5(%rip), %rdx    # 0x891970
callq 0x3620
leaq -0x33d(%rbp), %rsi
leaq 0x254b5(%rip), %rdi     # 0x38853
movb $0x0, %al
callq 0x8db0
movl $0x1, %edi
callq 0x130e0
xorl %edi, %edi
callq 0x10200
leaq 0x874943(%rip), %rdi    # 0x887d00
callq 0x20d0
leaq 0x254a3(%rip), %rdi     # 0x3886c
movb $0x0, %al
callq 0x8db0
leaq -0x668(%rbp), %rdi
leaq 0x87475a(%rip), %rsi    # 0x887b38
xorl %edx, %edx
callq 0x13560
leaq -0x330(%rbp), %rdi
leaq -0x668(%rbp), %rsi
movl $0x328, %edx            # imm = 0x328
callq 0x20f0
leaq 0x25499(%rip), %rdi     # 0x3889d
movb $0x0, %al
callq 0x8db0
leaq 0x8748ee(%rip), %rdi    # 0x887d00
callq 0x2290
leaq 0x2549b(%rip), %rdi     # 0x388b9
movb $0x0, %al
callq 0x8db0
movq $0x0, 0x8746f8(%rip) # 0x887b28
movb 0x8746ef(%rip), %al     # 0x887b25
testb $0x1, %al
jne 0x134f7
leaq 0x8746f3(%rip), %rdi    # 0x887b38
leaq 0xc0694(%rip), %rsi     # 0xd3ae0
movl $0x1, %edx
callq 0xe490
testb $0x1, %al
jne 0x1345c
jmp 0x1345e
jmp 0x1347d
leaq 0x25339(%rip), %rdi     # 0x3879e
leaq 0x25354(%rip), %rsi     # 0x387c0
movl $0x81, %edx
leaq 0x25356(%rip), %rcx     # 0x387ce
callq 0x20c0
leaq 0xc065c(%rip), %rax     # 0xd3ae0
movl 0x144(%rax), %edx
leaq 0x87e4df(%rip), %rdi    # 0x891970
leaq 0xc0818(%rip), %rsi     # 0xd3cb0
callq 0x15020
testb $0x1, %al
jne 0x134a3
jmp 0x134a5
jmp 0x134c4
leaq 0x2533d(%rip), %rdi     # 0x387e9
leaq 0x2530d(%rip), %rsi     # 0x387c0
movl $0x82, %edx
leaq 0x2530f(%rip), %rcx     # 0x387ce
callq 0x20c0
movq -0x328(%rbp), %rsi
leaq 0xc060e(%rip), %rdi     # 0xd3ae0
leaq 0xc07d7(%rip), %rdx     # 0xd3cb0
callq 0x3620
movq -0x328(%rbp), %rdi
callq 0x14ed0
callq 0x14e20
movl %eax, -0x334(%rbp)
jmp 0x134fe
movb $0x1, -0x335(%rbp)
xorl %edi, %edi
callq 0x130e0
leaq 0x8747f4(%rip), %rdi    # 0x887d00
callq 0x20d0
leaq 0x253d2(%rip), %rdi     # 0x388ea
movb $0x0, %al
callq 0x8db0
jmp 0x132b2
leaq 0x253f0(%rip), %rdi     # 0x3891b
movb $0x0, %al
callq 0x8db0
cmpl $0x0, -0x334(%rbp)
je 0x13546
movl -0x334(%rbp), %edi
callq 0x15390
xorl %eax, %eax
addq $0x670, %rsp            # imm = 0x670
popq %rbp
retq
nopw %cs:(%rax,%rax)