// File: /workspace/github_c_makefile_star2_O0/deplinenoise[P]tundra/src/BuildQueue.cpp
// Function: t2::AdvanceNode(t2::BuildQueue*, t2::ThreadState*, t2::NodeState*, t2::Mutex*)
static void AdvanceNode(BuildQueue* queue, ThreadState* thread_state, NodeState* node, Mutex* queue_lock)
  {
    Log(kSpam, "T=%d, [%d] Advancing %s\n",
        thread_state->m_ThreadIndex, node->m_Progress, node->m_MmapData->m_Annotation.Get());

    CHECK(!NodeStateIsCompleted(node));
    CHECK(NodeStateIsActive(node));
    CHECK(!NodeStateIsQueued(node));

    for (;;)
    {
      switch (node->m_Progress)
      {
        case BuildProgress::kInitial:
          node->m_Progress = SetupDependencies(queue, node);

          if (BuildProgress::kBlocked == node->m_Progress)
          {
            // Set ourselves as inactive until our dependencies are ready.
            NodeStateFlagInactive(node);
            return;
          }
          else
            break;

        case BuildProgress::kBlocked:
          CHECK(AllDependenciesReady(queue, node));
          node->m_Progress = BuildProgress::kUnblocked;
          break;

        case BuildProgress::kUnblocked:
          node->m_Progress = CheckInputSignature(queue, thread_state, node, queue_lock);
          break;

        case BuildProgress::kRunAction:
          node->m_Progress = RunAction(queue, thread_state, node, queue_lock);

          // If we couldn't make progress, we're a parked expensive node.
          // Another expensive job will put us back on the queue later when it
          // has finshed.
          if (BuildProgress::kRunAction == node->m_Progress)
            return;

          // Otherwise, we just ran our action. If we were an expensive node,
          // make sure to let other expensive nodes on to the cores now.
          if (node->m_MmapData->m_Flags & NodeData::kFlagExpensive)
          {
            --queue->m_ExpensiveRunning;
            CHECK(queue->m_ExpensiveRunning >= 0);

            // We were an expensive job. We can unpark another expensive job if
            // anything is waiting.
            UnparkExpensiveNode(queue);
          }
          break;

        case BuildProgress::kSucceeded:
        case BuildProgress::kUpToDate:
          node->m_BuildResult = 0;
          node->m_Progress    = BuildProgress::kCompleted;
          break;

        case BuildProgress::kFailed:
          queue->m_FailedNodeCount++;

          CondBroadcast(&queue->m_WorkAvailable);

          node->m_BuildResult = 1;
          node->m_Progress    = BuildProgress::kCompleted;
          break;

        case BuildProgress::kCompleted:
          queue->m_PendingNodeCount--;

          UnblockWaiters(queue, node);

          CondBroadcast(&queue->m_WorkAvailable);
          return;

        default:
          Croak("invalid node state progress");
          break;
      }
    }
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl 0x40(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
addq $0x8, %rdi
callq 0x6c00
movl -0x28(%rbp), %edx
movl -0x24(%rbp), %ecx
movq %rax, %r8
movl $0x10, %edi
leaq 0x1ec2b(%rip), %rsi     # 0x23b1d
movb $0x0, %al
callq 0x7a60
jmp 0x4efb
jmp 0x4efd
jmp 0x4eff
jmp 0x4f01
jmp 0x4f03
jmp 0x4f05
movq -0x18(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x2c(%rbp)
testl %eax, %eax
je 0x4f71
jmp 0x4f15
movl -0x2c(%rbp), %eax
subl $0x1, %eax
je 0x4fa8
jmp 0x4f23
movl -0x2c(%rbp), %eax
subl $0x2, %eax
je 0x4fbc
jmp 0x4f31
movl -0x2c(%rbp), %eax
subl $0x3, %eax
je 0x4fdf
jmp 0x4f3f
movl -0x2c(%rbp), %eax
addl $-0x64, %eax
subl $0x2, %eax
jb 0x5046
jmp 0x4f50
movl -0x2c(%rbp), %eax
subl $0x66, %eax
je 0x505e
jmp 0x4f5e
movl -0x2c(%rbp), %eax
subl $0xc8, %eax
je 0x5096
jmp 0x50c5
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5120
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x18(%rbp), %rcx
movl $0x1, %eax
cmpl 0x4(%rcx), %eax
jne 0x4fa3
movq -0x18(%rbp), %rdi
callq 0x6c40
jmp 0x50d8
jmp 0x50d3
jmp 0x4faa
jmp 0x4fac
movq -0x18(%rbp), %rax
movl $0x2, 0x4(%rax)
jmp 0x50d3
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x5240
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x4(%rax)
jmp 0x50d3
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x5960
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x18(%rbp), %rcx
movl $0x3, %eax
cmpl 0x4(%rcx), %eax
jne 0x5010
jmp 0x50d8
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x44(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x5041
movq -0x8(%rbp), %rax
movl 0x108(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x108(%rax)
jmp 0x5038
movq -0x8(%rbp), %rdi
callq 0x6130
jmp 0x50d3
movq -0x18(%rbp), %rax
movl $0x0, 0x1c(%rax)
movq -0x18(%rbp), %rax
movl $0xc8, 0x4(%rax)
jmp 0x50d3
movq -0x8(%rbp), %rax
movl 0xec(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xec(%rax)
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x6a30
movq -0x18(%rbp), %rax
movl $0x1, 0x1c(%rax)
movq -0x18(%rbp), %rax
movl $0xc8, 0x4(%rax)
jmp 0x50d3
movq -0x8(%rbp), %rax
movl 0xe8(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0xe8(%rax)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x61b0
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
callq 0x6a30
jmp 0x50d8
leaq 0x1ea6a(%rip), %rdi     # 0x23b36
movb $0x0, %al
callq 0x75a0
jmp 0x4f05
addq $0x30, %rsp
popq %rbp
retq
nop