// File: canzarlab[P]Trajan/src/BnG.cpp
// Function: BFBnBSolver::EvalOpen()
vector<BnBNode*> BFBnBSolver::EvalOpen()
{
    /*
      1. Solve nodes in open with up to thr_no threads.
      2. When all threads are finished pick the best node and return.

      Old code for reference:

      for (auto& it : Open)
      if (it->obj == 1 && !SolveNode(it, PGTOL, NUMTOL))
      it->obj = 2;

      sort(Open.begin(), Open.end(), [](BnBNode*& l, BnBNode*& r)
      { 
      return l->obj < r->obj; //return l->obj > r->obj; 
      });

      BnBNode* node = Open.back(); Open.pop_back();        
      return (node->obj < 1) ? node : nullptr;
    */
    thread thr_obj[thr_no];    
    vector<BnBNode*> thr_vec[thr_no];
    size_t k = 0;    

    for (auto& it : Open)
        if (it->obj == 1) 
            thr_vec[k % thr_no].push_back(it), ++k;
    k = min(k, thr_no);

    for (size_t i = 0; i < k; ++i)
        thr_obj[i] = thread(&BFBnBSolver::ThreadCallback, this, &thr_vec[i]); 

    for (size_t i = 0; i < k; ++i)
        thr_obj[i].join();

    sort(Open.begin(), Open.end(), [](BnBNode*& l, BnBNode*& r)
    { 
        return l->obj < r->obj; 
    });

    while (Open.size() && Open.back()->obj > 0)
        Open.pop_back();

    vector<BnBNode*> v; 
    for (size_t i = 0; Open.size() && i < thr_no; ++i)
        v.push_back(Open.back()), Open.pop_back();

    return v;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0xe0(%rbp)
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq 0x150(%rax), %rax
movq %rax, -0xc8(%rbp)
movq %rsp, %rcx
movq %rcx, -0x18(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0xc0(%rbp)
movq %rcx, %rsp
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
je 0xd4a31
movq -0xc0(%rbp), %rax
movq -0xc8(%rbp), %rdx
shlq $0x3, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0xf0(%rbp)
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0xd9430
movq -0xf8(%rbp), %rax
movq -0xf0(%rbp), %rcx
addq $0x8, %rax
cmpq %rcx, %rax
movq %rax, -0xe8(%rbp)
jne 0xd4a00
movq -0xd0(%rbp), %rax
movq 0x150(%rax), %rax
movq %rax, -0x108(%rbp)
leaq (%rax,%rax,2), %rcx
leaq 0xf(,%rcx,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x100(%rbp)
movq %rcx, %rsp
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0xd4ac7
movq -0x100(%rbp), %rax
movq -0x108(%rbp), %rcx
imulq $0x18, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x118(%rbp)
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0xd9350
movq -0x120(%rbp), %rax
movq -0x118(%rbp), %rcx
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, -0x110(%rbp)
jne 0xd4a96
movq -0xd0(%rbp), %rax
movq $0x0, -0x30(%rbp)
addq $0x160, %rax            # imm = 0x160
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0xd9170
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0xd91a0
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0xd91d0
testb $0x1, %al
jne 0xd4b10
jmp 0xd4b99
leaq -0x40(%rbp), %rdi
callq 0xd9210
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq (%rax), %rax
movsd 0x60(%rax), %xmm0
movsd 0x39137(%rip), %xmm1    # 0x10dc68
ucomisd %xmm1, %xmm0
jne 0xd4b89
jp 0xd4b89
movq -0xd0(%rbp), %rcx
movq -0x30(%rbp), %rax
movq 0x150(%rcx), %rcx
xorl %edx, %edx
divq %rcx
movq -0x100(%rbp), %rax
leaq (%rdx,%rdx,2), %rcx
leaq (%rax,%rcx,8), %rdi
movq -0x50(%rbp), %rsi
callq 0xd93a0
jmp 0xd4b6a
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xd4b89
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0xd4ede
jmp 0xd4b8b
leaq -0x40(%rbp), %rdi
callq 0xd9230
jmp 0xd4afa
movq -0xd0(%rbp), %rsi
addq $0x150, %rsi            # imm = 0x150
leaq -0x30(%rbp), %rdi
callq 0x156f0
movq %rax, -0x128(%rbp)
jmp 0xd4bb9
movq -0x128(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0xd4c6a
movq -0x100(%rbp), %rax
movq -0xd0(%rbp), %rcx
leaq -0x332(%rip), %rdx      # 0xd48c0
movq %rdx, -0x80(%rbp)
movq $0x0, -0x78(%rbp)
movq %rcx, -0x88(%rbp)
movq -0x68(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rax
movq %rax, -0x90(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x88(%rbp), %rdx
leaq -0x90(%rbp), %rcx
callq 0xd9450
jmp 0xd4c35
movq -0xc0(%rbp), %rdi
movq -0x68(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
leaq -0x70(%rbp), %rsi
callq 0xd9520
leaq -0x70(%rbp), %rdi
callq 0xbd7d0
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0xd4bcf
movq $0x0, -0x98(%rbp)
movq -0x98(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0xd4cb1
movq -0xc0(%rbp), %rax
movq -0x98(%rbp), %rcx
leaq (%rax,%rcx,8), %rdi
callq 0xa770
jmp 0xd4c9b
jmp 0xd4c9d
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0xd4c75
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
movq %rdi, -0x130(%rbp)
callq 0xd9170
movq -0x130(%rbp), %rdi
movq %rax, -0xa0(%rbp)
callq 0xd91a0
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0xd4fe0
jmp 0xd4cfa
jmp 0xd4cfc
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd9410
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x131(%rbp)
je 0xd4d4b
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd9560
movq (%rax), %rax
movsd 0x60(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
seta %al
movb %al, -0x131(%rbp)
movb -0x131(%rbp), %al
testb $0x1, %al
jne 0xd4d57
jmp 0xd4d6c
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd95a0
jmp 0xd4cfc
movq -0xe0(%rbp), %rdi
movb $0x0, -0xaa(%rbp)
callq 0xd9350
movq $0x0, -0xb8(%rbp)
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd9410
movq %rax, %rcx
xorl %eax, %eax
cmpq $0x0, %rcx
movb %al, -0x132(%rbp)
je 0xd4dcc
movq -0xd0(%rbp), %rcx
movq -0xb8(%rbp), %rax
cmpq 0x150(%rcx), %rax
setb %al
movb %al, -0x132(%rbp)
movb -0x132(%rbp), %al
testb $0x1, %al
jne 0xd4dd8
jmp 0xd4e43
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd9560
movq -0xe0(%rbp), %rdi
movq %rax, %rsi
callq 0xd93a0
jmp 0xd4dfc
movq -0xd0(%rbp), %rdi
addq $0x160, %rdi            # imm = 0x160
callq 0xd95a0
movq -0xb8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
jmp 0xd4d8a
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
callq 0xd9250
jmp 0xd4ede
movb $0x1, -0xaa(%rbp)
testb $0x1, -0xaa(%rbp)
jne 0xd4e5f
movq -0xe0(%rbp), %rdi
callq 0xd9250
movq -0x100(%rbp), %rcx
movq -0x108(%rbp), %rax
imulq $0x18, %rax, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x140(%rbp)
je 0xd4eb4
movq -0x140(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x148(%rbp)
callq 0xd9250
movq -0x100(%rbp), %rcx
movq -0x148(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x140(%rbp)
jne 0xd4e83
movq -0xc0(%rbp), %rcx
movq -0xc8(%rbp), %rdx
shlq $0x3, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x150(%rbp)
je 0xd4f8a
jmp 0xd4f59
movq -0x100(%rbp), %rcx
movq -0x108(%rbp), %rax
imulq $0x18, %rax, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x158(%rbp)
je 0xd4f33
movq -0x158(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x160(%rbp)
callq 0xd9250
movq -0x100(%rbp), %rcx
movq -0x160(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x158(%rbp)
jne 0xd4f02
movq -0xc0(%rbp), %rcx
movq -0xc8(%rbp), %rdx
shlq $0x3, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0x168(%rbp)
je 0xd4fce
jmp 0xd4f9d
movq -0x150(%rbp), %rdi
addq $-0x8, %rdi
movq %rdi, -0x170(%rbp)
callq 0xbd7d0
movq -0xc0(%rbp), %rcx
movq -0x170(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x150(%rbp)
jne 0xd4f59
movq -0xd8(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, %rsp
movq %rbp, %rsp
popq %rbp
retq
movq -0x168(%rbp), %rdi
addq $-0x8, %rdi
movq %rdi, -0x178(%rbp)
callq 0xbd7d0
movq -0xc0(%rbp), %rcx
movq -0x178(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x168(%rbp)
jne 0xd4f9d
jmp 0xd4fd0
movq -0x58(%rbp), %rdi
callq 0xa7c0
nopl (%rax)