1 | // Copyright 2016 Google Inc. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef NINJA_STATUS_H_ |
16 | #define NINJA_STATUS_H_ |
17 | |
18 | #include <map> |
19 | #include <string> |
20 | |
21 | #include "build.h" |
22 | #include "line_printer.h" |
23 | |
24 | /// Abstract interface to object that tracks the status of a build: |
25 | /// completion fraction, printing updates. |
26 | struct Status { |
27 | virtual void PlanHasTotalEdges(int total) = 0; |
28 | virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis) = 0; |
29 | virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, |
30 | bool success, const std::string& output) = 0; |
31 | virtual void BuildLoadDyndeps() = 0; |
32 | virtual void BuildStarted() = 0; |
33 | virtual void BuildFinished() = 0; |
34 | |
35 | virtual void Info(const char* msg, ...) = 0; |
36 | virtual void Warning(const char* msg, ...) = 0; |
37 | virtual void Error(const char* msg, ...) = 0; |
38 | |
39 | virtual ~Status() { } |
40 | }; |
41 | |
42 | /// Implementation of the Status interface that prints the status as |
43 | /// human-readable strings to stdout |
44 | struct StatusPrinter : Status { |
45 | explicit StatusPrinter(const BuildConfig& config); |
46 | virtual void PlanHasTotalEdges(int total); |
47 | virtual void BuildEdgeStarted(const Edge* edge, int64_t start_time_millis); |
48 | virtual void BuildEdgeFinished(Edge* edge, int64_t end_time_millis, |
49 | bool success, const std::string& output); |
50 | virtual void BuildLoadDyndeps(); |
51 | virtual void BuildStarted(); |
52 | virtual void BuildFinished(); |
53 | |
54 | virtual void Info(const char* msg, ...); |
55 | virtual void Warning(const char* msg, ...); |
56 | virtual void Error(const char* msg, ...); |
57 | |
58 | virtual ~StatusPrinter() { } |
59 | |
60 | /// Format the progress status string by replacing the placeholders. |
61 | /// See the user manual for more information about the available |
62 | /// placeholders. |
63 | /// @param progress_status_format The format of the progress status. |
64 | /// @param status The status of the edge. |
65 | std::string FormatProgressStatus(const char* progress_status_format, |
66 | int64_t time_millis) const; |
67 | |
68 | private: |
69 | void PrintStatus(const Edge* edge, int64_t time_millis); |
70 | |
71 | const BuildConfig& config_; |
72 | |
73 | int started_edges_, finished_edges_, total_edges_, running_edges_; |
74 | int64_t time_millis_; |
75 | |
76 | /// Prints progress output. |
77 | LinePrinter printer_; |
78 | |
79 | /// The custom progress status format to use. |
80 | const char* progress_status_format_; |
81 | |
82 | template<size_t S> |
83 | void SnprintfRate(double rate, char(&buf)[S], const char* format) const { |
84 | if (rate == -1) |
85 | snprintf(buf, S, "?" ); |
86 | else |
87 | snprintf(buf, S, format, rate); |
88 | } |
89 | |
90 | struct SlidingRateInfo { |
91 | SlidingRateInfo(int n) : rate_(-1), N(n), last_update_(-1) {} |
92 | |
93 | double rate() { return rate_; } |
94 | |
95 | void UpdateRate(int update_hint, int64_t time_millis) { |
96 | if (update_hint == last_update_) |
97 | return; |
98 | last_update_ = update_hint; |
99 | |
100 | if (times_.size() == N) |
101 | times_.pop(); |
102 | times_.push(time_millis); |
103 | if (times_.back() != times_.front()) |
104 | rate_ = times_.size() / ((times_.back() - times_.front()) / 1e3); |
105 | } |
106 | |
107 | private: |
108 | double rate_; |
109 | const size_t N; |
110 | std::queue<double> times_; |
111 | int last_update_; |
112 | }; |
113 | |
114 | mutable SlidingRateInfo current_rate_; |
115 | }; |
116 | |
117 | #endif // NINJA_STATUS_H_ |
118 | |