diff options
author | Jeongik Cha <jeongik@google.com> | 2023-11-27 11:17:48 +0900 |
---|---|---|
committer | Jeongik Cha <jeongik@google.com> | 2023-11-27 11:17:48 +0900 |
commit | 36373213c7365ceb8f7e53a6cee3a5e6d68d0723 (patch) | |
tree | f68751b2e5fa8f9d0a024d428a88b76d8fb43fbf | |
parent | 093a41b354aa33de3d2f6bcf6a23ff2a81f93f23 (diff) | |
download | ninja-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.pb | bin | 1389 -> 1486 bytes | |||
-rw-r--r-- | src/build.cc | 24 | ||||
-rw-r--r-- | src/build.h | 1 | ||||
-rw-r--r-- | src/build_test.cc | 2 | ||||
-rw-r--r-- | src/frontend.pb.h | 30 | ||||
-rw-r--r-- | src/frontend.proto | 2 | ||||
-rw-r--r-- | src/graph.h | 2 | ||||
-rw-r--r-- | src/status.cc | 14 | ||||
-rw-r--r-- | src/status.h | 10 |
9 files changed, 77 insertions, 8 deletions
diff --git a/frontend/frontend.pb b/frontend/frontend.pb Binary files differindex 8795ecd..87685e8 100644 --- a/frontend/frontend.pb +++ b/frontend/frontend.pb 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 |