summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Niklas Hasse <jhasse@bixense.com>2024-02-29 17:59:19 (GMT)
committerGitHub <noreply@github.com>2024-02-29 17:59:19 (GMT)
commitbf6409ad5aa0c92db0add01c959e276fdcc7fc23 (patch)
tree3059c3e5170712df29f2345a69bf715b5969fd57 /src
parent460dff81192617168ea05eae0b7816054f2aa32d (diff)
parent8a2575e432b85baecb0054cc570db69f074c2633 (diff)
downloadNinja-bf6409ad5aa0c92db0add01c959e276fdcc7fc23.zip
Ninja-bf6409ad5aa0c92db0add01c959e276fdcc7fc23.tar.gz
Ninja-bf6409ad5aa0c92db0add01c959e276fdcc7fc23.tar.bz2
Merge pull request #1949 from Flowdalic/load-capacity
Consider the remaining job capacity in main loop
Diffstat (limited to 'src')
-rw-r--r--src/build.cc55
-rw-r--r--src/build.h2
-rw-r--r--src/build_test.cc11
3 files changed, 51 insertions, 17 deletions
diff --git a/src/build.cc b/src/build.cc
index e0c3939..9c5cb66 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -18,6 +18,8 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <climits>
+#include <stdint.h>
#include <functional>
#if defined(__SVR4) && defined(__sun)
@@ -46,7 +48,7 @@ struct DryRunCommandRunner : public CommandRunner {
virtual ~DryRunCommandRunner() {}
// Overridden from CommandRunner:
- virtual bool CanRunMore() const;
+ virtual size_t CanRunMore() const;
virtual bool StartCommand(Edge* edge);
virtual bool WaitForCommand(Result* result);
@@ -54,8 +56,8 @@ struct DryRunCommandRunner : public CommandRunner {
queue<Edge*> finished_;
};
-bool DryRunCommandRunner::CanRunMore() const {
- return true;
+size_t DryRunCommandRunner::CanRunMore() const {
+ return SIZE_MAX;
}
bool DryRunCommandRunner::StartCommand(Edge* edge) {
@@ -569,7 +571,7 @@ void Plan::Dump() const {
struct RealCommandRunner : public CommandRunner {
explicit RealCommandRunner(const BuildConfig& config) : config_(config) {}
virtual ~RealCommandRunner() {}
- virtual bool CanRunMore() const;
+ virtual size_t CanRunMore() const;
virtual bool StartCommand(Edge* edge);
virtual bool WaitForCommand(Result* result);
virtual vector<Edge*> GetActiveEdges();
@@ -592,12 +594,26 @@ void RealCommandRunner::Abort() {
subprocs_.Clear();
}
-bool RealCommandRunner::CanRunMore() const {
+size_t RealCommandRunner::CanRunMore() const {
size_t subproc_number =
subprocs_.running_.size() + subprocs_.finished_.size();
- return (int)subproc_number < config_.parallelism
- && ((subprocs_.running_.empty() || config_.max_load_average <= 0.0f)
- || GetLoadAverage() < config_.max_load_average);
+
+ int64_t capacity = config_.parallelism - subproc_number;
+
+ if (config_.max_load_average > 0.0f) {
+ int load_capacity = config_.max_load_average - GetLoadAverage();
+ if (load_capacity < capacity)
+ capacity = load_capacity;
+ }
+
+ if (capacity < 0)
+ capacity = 0;
+
+ if (capacity == 0 && subprocs_.running_.empty())
+ // Ensure that we make progress.
+ capacity = 1;
+
+ return capacity;
}
bool RealCommandRunner::StartCommand(Edge* edge) {
@@ -749,8 +765,13 @@ bool Builder::Build(string* err) {
// Second, we attempt to wait for / reap the next finished command.
while (plan_.more_to_do()) {
// See if we can start any more commands.
- if (failures_allowed && command_runner_->CanRunMore()) {
- if (Edge* edge = plan_.FindWork()) {
+ if (failures_allowed) {
+ size_t capacity = command_runner_->CanRunMore();
+ while (capacity > 0) {
+ Edge* edge = plan_.FindWork();
+ if (!edge)
+ break;
+
if (edge->GetBindingBool("generator")) {
scan_.build_log()->Close();
}
@@ -769,11 +790,19 @@ bool Builder::Build(string* err) {
}
} else {
++pending_commands;
- }
- // We made some progress; go back to the main loop.
- continue;
+ --capacity;
+
+ // Re-evaluate capacity.
+ size_t current_capacity = command_runner_->CanRunMore();
+ if (current_capacity < capacity)
+ capacity = current_capacity;
+ }
}
+
+ // We are finished with all work items and have no pending
+ // commands. Therefore, break out of the main loop.
+ if (pending_commands == 0 && !plan_.more_to_do()) break;
}
// See if we can reap any finished commands.
diff --git a/src/build.h b/src/build.h
index 2885f41..471f0b2 100644
--- a/src/build.h
+++ b/src/build.h
@@ -145,7 +145,7 @@ private:
/// RealCommandRunner is an implementation that actually runs commands.
struct CommandRunner {
virtual ~CommandRunner() {}
- virtual bool CanRunMore() const = 0;
+ virtual size_t CanRunMore() const = 0;
virtual bool StartCommand(Edge* edge) = 0;
/// The result of waiting for a command.
diff --git a/src/build_test.cc b/src/build_test.cc
index 71bf55c..c9cc647 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -15,6 +15,8 @@
#include "build.h"
#include <assert.h>
+#include <climits>
+#include <stdint.h>
#include "build_log.h"
#include "deps_log.h"
@@ -519,7 +521,7 @@ struct FakeCommandRunner : public CommandRunner {
max_active_edges_(1), fs_(fs) {}
// CommandRunner impl
- virtual bool CanRunMore() const;
+ virtual size_t CanRunMore() const;
virtual bool StartCommand(Edge* edge);
virtual bool WaitForCommand(Result* result);
virtual vector<Edge*> GetActiveEdges();
@@ -620,8 +622,11 @@ void BuildTest::RebuildTarget(const string& target, const char* manifest,
builder.command_runner_.release();
}
-bool FakeCommandRunner::CanRunMore() const {
- return active_edges_.size() < max_active_edges_;
+size_t FakeCommandRunner::CanRunMore() const {
+ if (active_edges_.size() < max_active_edges_)
+ return SIZE_MAX;
+
+ return 0;
}
bool FakeCommandRunner::StartCommand(Edge* edge) {