summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/build.cc24
-rw-r--r--src/build.h58
-rw-r--r--src/metrics.h9
3 files changed, 53 insertions, 38 deletions
diff --git a/src/build.cc b/src/build.cc
index e1aaad1..5a0c3b3 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -42,8 +42,7 @@ BuildStatus::BuildStatus(const BuildConfig& config)
start_time_millis_(GetTimeMillis()),
started_edges_(0), finished_edges_(0), total_edges_(0),
have_blank_line_(true), progress_status_format_(NULL),
- overall_rate_(), current_rate_(),
- current_rate_average_count_(config.parallelism) {
+ overall_rate_(), current_rate_(config.parallelism) {
#ifndef _WIN32
const char* term = getenv("TERM");
smart_terminal_ = isatty(1) && term && string(term) != "dumb";
@@ -136,7 +135,8 @@ void BuildStatus::BuildFinished() {
printf("\n");
}
-string BuildStatus::FormatProgressStatus(const char* progress_status_format) const {
+string BuildStatus::FormatProgressStatus(
+ const char* progress_status_format) const {
string out;
char buf[32];
for (const char* s = progress_status_format; *s != '\0'; ++s) {
@@ -177,30 +177,24 @@ string BuildStatus::FormatProgressStatus(const char* progress_status_format) con
out += buf;
break;
- // Overall finished edges per second.
+ // Overall finished edges per second.
case 'o':
- overall_rate_.UpdateRate(finished_edges_, finished_edges_);
+ overall_rate_.UpdateRate(finished_edges_);
overall_rate_.snprinfRate(buf, "%.1f");
out += buf;
break;
- // Current rate, average over the last '-j' jobs.
+ // Current rate, average over the last '-j' jobs.
case 'c':
- // TODO use sliding window?
- if (finished_edges_ > current_rate_.last_update() &&
- finished_edges_ - current_rate_.last_update() == current_rate_average_count_) {
- current_rate_.UpdateRate(current_rate_average_count_, finished_edges_);
- current_rate_.Restart();
- }
- current_rate_.snprinfRate(buf, "%.0f");
+ current_rate_.UpdateRate(finished_edges_);
+ current_rate_.snprinfRate(buf, "%.1f");
out += buf;
break;
- default: {
+ default:
Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s);
return "";
}
- }
} else {
out.push_back(*s);
}
diff --git a/src/build.h b/src/build.h
index 3e7a144..0902a4c 100644
--- a/src/build.h
+++ b/src/build.h
@@ -201,37 +201,59 @@ struct BuildStatus {
const char* progress_status_format_;
struct RateInfo {
- RateInfo() : last_update_(0), rate_(-1) {}
-
- double rate() const { return rate_; }
- int last_update() const { return last_update_; }
- void Restart() { return stopwatch_.Restart(); }
-
- double UpdateRate(int edges, int update_hint) {
- if (update_hint != last_update_) {
- rate_ = edges / stopwatch_.Elapsed() + 0.5;
- last_update_ = update_hint;
- }
- return rate_;
+ RateInfo() : rate_(-1) {}
+
+ void Restart() { stopwatch_.Restart(); }
+
+ void UpdateRate(int edges) {
+ if (edges && stopwatch_.Elapsed())
+ rate_ = edges / stopwatch_.Elapsed();
+ }
+
+ template<class T>
+ void snprinfRate(T buf, const char* format) {
+ if (rate_ == -1) snprintf(buf, sizeof(buf), "?");
+ else snprintf(buf, sizeof(buf), format, rate_);
+ }
+
+ private:
+ Stopwatch stopwatch_;
+ double rate_;
+ };
+
+ struct SlidingRateInfo {
+ SlidingRateInfo(int n) : N(n), last_update_(-1), rate_(-1) {}
+
+ void Restart() { stopwatch_.Restart(); }
+
+ void UpdateRate(int update_hint) {
+ if (update_hint == last_update_)
+ return;
+ last_update_ = update_hint;
+
+ if (times_.size() == N)
+ times_.pop();
+ times_.push(stopwatch_.Elapsed());
+ if (times_.back() != times_.front())
+ rate_ = times_.size() / (times_.back() - times_.front());
}
template<class T>
void snprinfRate(T buf, const char* format) {
- if (rate_ == -1)
- snprintf(buf, sizeof(buf), "?");
- else
- snprintf(buf, sizeof(buf), format, rate_);
+ if (rate_ == -1) snprintf(buf, sizeof(buf), "?");
+ else snprintf(buf, sizeof(buf), format, rate_);
}
private:
+ const size_t N;
+ std::queue<double> times_;
Stopwatch stopwatch_;
int last_update_;
double rate_;
};
mutable RateInfo overall_rate_;
- mutable RateInfo current_rate_;
- const int current_rate_average_count_;
+ mutable SlidingRateInfo current_rate_;
#ifdef _WIN32
void* console_;
diff --git a/src/metrics.h b/src/metrics.h
index f5ac0de..a4ef9f7 100644
--- a/src/metrics.h
+++ b/src/metrics.h
@@ -59,19 +59,18 @@ private:
};
/// Get the current time as relative to some epoch.
-/// Epoch varies between platforms; only useful for measuring elapsed
-/// time.
+/// Epoch varies between platforms; only useful for measuring elapsed time.
int64_t GetTimeMillis();
-/// A simple stopwatch which retruns the time
-// in seconds since Restart() was called
+/// A simple stopwatch which returns the time
+/// in seconds since Restart() was called.
class Stopwatch
{
public:
Stopwatch() : started_(0) {}
- /// Seconds since Restart() call
+ /// Seconds since Restart() call.
double Elapsed() const { return 1e-6 * static_cast<double>(Now() - started_); }
void Restart() { started_ = Now(); }