46ADBTMQAHQAPW3OCI24F4I5DVK5N5QVHUA4TQVB6HFN337CHAVQC /* Find a machine with a free slot and find a step to runon it. Once we find such a pair, we restart the outerloop because the machine sorting will have changed. */keepGoing = false;for (auto & mi : machinesSorted) {// FIXME: can we lose a wakeup if a builder exits concurrently?if (mi.machine->state->currentJobs >= mi.machine->maxJobs) continue;
//printMsg(lvlDebug, format("%1% runnable builds") % runnable_->size());/* FIXME: we're holding the runnable lock too longhere. This could be more efficient. */
runnableSorted.reserve(runnable_->size());
}runnableSorted.push_back(step);}}sort(runnableSorted.begin(), runnableSorted.end(),[](const Step::ptr & a, const Step::ptr & b){auto a_(a->state.lock());auto b_(b->state.lock()); // FIXME: deadlock?return a_->lowestBuildID < b_->lowestBuildID;});/* Find a machine with a free slot and find a step to runon it. Once we find such a pair, we restart the outerloop because the machine sorting will have changed. */keepGoing = false;for (auto & mi : machinesSorted) {if (mi.machine->state->currentJobs >= mi.machine->maxJobs) continue;for (auto & step : runnableSorted) {/* Can this machine do this step? */if (!mi.machine->supportsStep(step)) continue;/* Let's do this step. Remove it from the runnablelist. FIXME: O(n). */{auto runnable_(runnable.lock());bool removed = false;for (auto i = runnable_->begin(); i != runnable_->end(); )if (i->lock() == step) {i = runnable_->erase(i);removed = true;break;} else ++i;assert(removed);
}void visitDependencies(std::function<void(Step::ptr)> visitor, Step::ptr start){std::set<Step::ptr> queued;std::queue<Step::ptr> todo;todo.push(start);while (!todo.empty()) {auto step = todo.front();todo.pop();visitor(step);auto state(step->state.lock());for (auto & dep : state->deps)if (queued.find(dep) == queued.end()) {queued.insert(dep);todo.push(dep);}}
/* Update the lowest build ID field of each dependency. Thisis used by the dispatcher to start steps in order of buildID. */visitDependencies([&](const Step::ptr & step) {auto step_(step->state.lock());step_->lowestBuildID = std::min(step_->lowestBuildID, build->id);}, build->toplevel);