aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongik Cha <jeongik@google.com>2023-11-27 11:17:48 +0900
committerJeongik Cha <jeongik@google.com>2023-11-27 11:17:48 +0900
commit36373213c7365ceb8f7e53a6cee3a5e6d68d0723 (patch)
treef68751b2e5fa8f9d0a024d428a88b76d8fb43fbf
parent093a41b354aa33de3d2f6bcf6a23ff2a81f93f23 (diff)
downloadninja-36373213c7365ceb8f7e53a6cee3a5e6d68d0723.tar.gz
Add estimated_total_time/critical_path_time in StatusSerializer
To predict ETA for the build, addied the fields Bug: 292304818 Test: check if the fields are included in protobuf msg Change-Id: Ifb7b1a9e8dbc3788e478d3186356bbf1879edc89
-rw-r--r--frontend/frontend.pbbin1389 -> 1486 bytes
-rw-r--r--src/build.cc24
-rw-r--r--src/build.h1
-rw-r--r--src/build_test.cc2
-rw-r--r--src/frontend.pb.h30
-rw-r--r--src/frontend.proto2
-rw-r--r--src/graph.h2
-rw-r--r--src/status.cc14
-rw-r--r--src/status.h10
9 files changed, 77 insertions, 8 deletions
diff --git a/frontend/frontend.pb b/frontend/frontend.pb
index 8795ecd..87685e8 100644
--- a/frontend/frontend.pb
+++ b/frontend/frontend.pb
Binary files differ
diff --git a/src/build.cc b/src/build.cc
index 4ccfaf3..3f6bb81 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -656,9 +656,15 @@ void Builder::RefreshPriority(const std::vector<Node*>& start_nodes) {
return data_source.Get(edge->outputs_[0]->globalPath().h).value_or(1);
} else if (config_.ninja_log_as_weight_list) {
if (scan_.build_log()) {
- auto* entry = scan_.build_log()->LookupByOutput(edge->outputs_[0]->globalPath());
- if (entry) {
- return entry->end_time - entry->start_time + 1;
+ if (edge->estimated_time() == -1) {
+ auto* entry = scan_.build_log()->LookupByOutput(edge->outputs_[0]->globalPath());
+ if (entry) {
+ edge->estimated_time_ = entry->end_time - entry->start_time + 1;
+ status_->AddEstimatedTime(edge->estimated_time());
+ return edge->estimated_time();
+ }
+ } else {
+ return edge->estimated_time();
}
}
return 1;
@@ -675,13 +681,13 @@ void Builder::RefreshPriority(const std::vector<Node*>& start_nodes) {
auto acc = p.second;
if (!e) {
- return std::unordered_map<Edge*, int64_t>();
+ return std::make_pair(0L, std::unordered_map<Edge*, int64_t>());
}
auto run = weight_getter(e);
auto new_priority = run + acc;
// Skip if priority isn't updated
if (new_priority <= e->priority()) {
- return std::unordered_map<Edge*, int64_t>();
+ return std::make_pair(e->priority(), std::unordered_map<Edge*, int64_t>());
}
e->priority_ = new_priority;
@@ -704,12 +710,15 @@ void Builder::RefreshPriority(const std::vector<Node*>& start_nodes) {
next_todo_map.try_emplace(ne, e->priority());
}
}
- return next_todo_map;
+ return std::make_pair(e->priority(), next_todo_map);
});
todos.clear();
std::unordered_map<Edge*, int64_t> next_todo_map_total;
- for (const auto& todo_map : result) {
+ for (const auto& [priority, todo_map] : result) {
+ if (config_.ninja_log_as_weight_list) {
+ critical_time_millis_ = std::max(critical_time_millis_, priority);
+ }
for (const auto& [k, v] : todo_map) {
auto [it, inserted] = next_todo_map_total.try_emplace(k, v);
if (!inserted) {
@@ -721,6 +730,7 @@ void Builder::RefreshPriority(const std::vector<Node*>& start_nodes) {
todos.emplace_back(key, value);
}
}
+ status_->SetCriticalPathTime(critical_time_millis_);
}
bool Builder::AddTargets(const std::vector<Node*> &nodes, string* err) {
diff --git a/src/build.h b/src/build.h
index e58ac33..41afa33 100644
--- a/src/build.h
+++ b/src/build.h
@@ -299,6 +299,7 @@ struct Builder {
/// Time the build started.
int64_t start_time_millis_;
+ int64_t critical_time_millis_;
DiskInterface* disk_interface_;
DependencyScan scan_;
diff --git a/src/build_test.cc b/src/build_test.cc
index 6957bb4..c8814ab 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -496,6 +496,8 @@ struct FakeStatus : public Status {
virtual void Debug(const char* msg, ...) {}
virtual void Info(const char* msg, ...) {}
virtual void Error(const char* msg, ...) {}
+ virtual void AddEstimatedTime(int64_t estimated_time_millis) {}
+ virtual void SetCriticalPathTime(int64_t critical_path_time_millis) {}
virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis,
const CommandRunner::Result* result) {
diff --git a/src/frontend.pb.h b/src/frontend.pb.h
index d5474a1..86c1b76 100644
--- a/src/frontend.pb.h
+++ b/src/frontend.pb.h
@@ -54,12 +54,20 @@ struct Status {
bool has_parallelism_;
bool verbose_;
bool has_verbose_;
+ uint32_t critical_path_time_;
+ bool has_critical_path_time_;
+ uint32_t estimated_total_time_;
+ bool has_estimated_total_time_;
BuildStarted() {
has_parallelism_ = false;
parallelism_ = static_cast< uint32_t >(0);
has_verbose_ = false;
verbose_ = static_cast< bool >(0);
+ has_critical_path_time_ = false;
+ critical_path_time_ = static_cast< uint32_t >(0);
+ has_estimated_total_time_ = false;
+ estimated_total_time_ = static_cast< uint32_t >(0);
}
BuildStarted(const BuildStarted&);
@@ -68,18 +76,24 @@ struct Status {
void SerializeToOstream(std::ostream* output__) const {
WriteVarint32(output__, 1, parallelism_);
WriteVarint32(output__, 2, verbose_);
+ WriteVarint32(output__, 3, critical_path_time_);
+ WriteVarint32(output__, 4, estimated_total_time_);
}
size_t ByteSizeLong() const {
size_t size = 0;
size += VarintSize32(parallelism_) + 1;
size += VarintSizeBool(verbose_) + 1;
+ size += VarintSize32(critical_path_time_) + 1;
+ size += VarintSize32(estimated_total_time_) + 1;
return size;
}
void Clear() {
parallelism_ = static_cast< uint32_t >(0);
verbose_ = static_cast< bool >(0);
+ critical_path_time_ = static_cast< uint32_t >(0);
+ estimated_total_time_ = static_cast< uint32_t >(0);
}
uint32_t* mutable_parallelism() {
@@ -98,6 +112,22 @@ struct Status {
has_verbose_ = true;
verbose_ = value;
}
+ uint32_t* mutable_critical_path_time() {
+ has_critical_path_time_ = true;
+ return &critical_path_time_;
+ }
+ void set_critical_path_time(const uint32_t& value) {
+ has_critical_path_time_ = true;
+ critical_path_time_ = value;
+ }
+ uint32_t* mutable_estimated_total_time() {
+ has_estimated_total_time_ = true;
+ return &estimated_total_time_;
+ }
+ void set_estimated_total_time(const uint32_t& value) {
+ has_estimated_total_time_ = true;
+ estimated_total_time_ = value;
+ }
};
struct BuildFinished {
diff --git a/src/frontend.proto b/src/frontend.proto
index 45b428a..4a58726 100644
--- a/src/frontend.proto
+++ b/src/frontend.proto
@@ -29,6 +29,8 @@ message Status {
optional uint32 parallelism = 1;
// Verbose value passed to ninja.
optional bool verbose = 2;
+ optional uint32 critical_path_time = 3;
+ optional uint32 estimated_total_time = 4;
}
message BuildFinished {
diff --git a/src/graph.h b/src/graph.h
index 04bbf84..8e15b27 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -465,6 +465,7 @@ public:
bool precomputed_dirtiness_ = false;
size_t id_ = 0;
int64_t priority_ = 0;
+ int64_t estimated_time_ = -1;
bool outputs_ready_ = false;
bool deps_loaded_ = false;
bool deps_missing_ = false;
@@ -481,6 +482,7 @@ public:
// After that, it is also updated from dependents.
// The final priority would be the sum of the critical path between this edge and the target edge.
int64_t priority() const { return priority_; }
+ int64_t estimated_time() const { return estimated_time_; }
bool outputs_ready() const { return outputs_ready_; }
// There are three types of inputs.
diff --git a/src/status.cc b/src/status.cc
index 445771b..1d809b4 100644
--- a/src/status.cc
+++ b/src/status.cc
@@ -136,6 +136,15 @@ void StatusPrinter::BuildFinished() {
printer_.PrintOnNewLine("");
}
+void StatusSerializer::AddEstimatedTime(int64_t estimated_time_millis) {
+ estimated_total_time_millis_ += estimated_time_millis;
+ estimated_edges_++;
+}
+
+void StatusSerializer::SetCriticalPathTime(int64_t critical_path_time_millis) {
+ critical_path_time_millis_ = critical_path_time_millis;
+}
+
string StatusPrinter::FormatProgressStatus(const char* progress_status_format,
int64_t time_millis) const {
string out;
@@ -388,6 +397,11 @@ void StatusSerializer::BuildStarted() {
ninja::Status::BuildStarted* build_started = proto_.mutable_build_started();
build_started->set_parallelism(config_.parallelism);
+ // It's meaningful only if more than half of total_edges are estimated.
+ if (estimated_edges_ > total_edges_ * 0.5) {
+ build_started->set_critical_path_time(critical_path_time_millis_);
+ build_started->set_estimated_total_time(estimated_total_time_millis_ * total_edges_ / estimated_edges_);
+ }
build_started->set_verbose((config_.verbosity == BuildConfig::VERBOSE));
Send();
diff --git a/src/status.h b/src/status.h
index ba6381b..75e5469 100644
--- a/src/status.h
+++ b/src/status.h
@@ -40,7 +40,8 @@ struct Status {
virtual void Info(const char* msg, ...) = 0;
virtual void Warning(const char* msg, ...) = 0;
virtual void Error(const char* msg, ...) = 0;
-
+ virtual void AddEstimatedTime(int64_t estimated_time_millis) = 0;
+ virtual void SetCriticalPathTime(int64_t critical_path_time_millis) = 0;
virtual ~Status() { }
};
@@ -56,6 +57,8 @@ struct StatusPrinter : Status {
virtual void BuildStarted();
virtual void BuildFinished();
+ virtual void AddEstimatedTime(int64_t estimated_time_millis) { /* Not supported */ }
+ virtual void SetCriticalPathTime(int64_t critical_path_time_millis) { /* Not supported */ }
virtual void Debug(const char* msg, ...);
virtual void Info(const char* msg, ...);
virtual void Warning(const char* msg, ...);
@@ -144,6 +147,9 @@ struct StatusSerializer : Status {
virtual void Warning(const char* msg, ...);
virtual void Error(const char* msg, ...);
+ virtual void AddEstimatedTime(int64_t estimated_time_millis);
+ virtual void SetCriticalPathTime(int64_t critical_path_time_millis);
+
const BuildConfig& config_;
FILE* f_;
@@ -159,6 +165,8 @@ struct StatusSerializer : Status {
private:
void Message(ninja::Status::Message::Level level, const char* msg, va_list ap);
void Send();
+
+ int64_t estimated_total_time_millis_, critical_path_time_millis_, estimated_edges_;
};
#endif // !_WIN32