summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Dawson <brucedawson@chromium.org>2021-10-01 14:39:03 -0700
committerBruce Dawson <brucedawson@chromium.org>2021-10-01 14:39:29 -0700
commit95d7e865a15e22e516ce7cc681a7f801d6650cfb (patch)
treecdc87d4b494fd788bf80fbbaac7840ceedcf728b
parentb337bbfd57172b8222048848feabc911af107d1a (diff)
downloadninja-95d7e865a15e22e516ce7cc681a7f801d6650cfb.tar.gz
Disable stdout buffering in real_main
Previously stdout buffering was disabled in the LinePrinter constructor. This worked for a long time but ultimately this side-effect caused a performance bug (issue #2018) in tools such as -t deps. Moving the disabling of buffering into real_main and only disabling buffering when a tool is not used makes the desired semantics clearer and restores the lost performance. This fixes issue #2018. It has been tested and a 10x speedup was seen relative to the tip-of-tree version.
-rw-r--r--src/line_printer.cc5
-rw-r--r--src/ninja.cc11
2 files changed, 11 insertions, 5 deletions
diff --git a/src/line_printer.cc b/src/line_printer.cc
index 3138960..a3d0528 100644
--- a/src/line_printer.cc
+++ b/src/line_printer.cc
@@ -37,14 +37,9 @@ LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) {
#ifndef _WIN32
smart_terminal_ = isatty(1) && term && string(term) != "dumb";
#else
- // Disable output buffer. It'd be nice to use line buffering but
- // MSDN says: "For some systems, [_IOLBF] provides line
- // buffering. However, for Win32, the behavior is the same as _IOFBF
- // - Full Buffering."
if (term && string(term) == "dumb") {
smart_terminal_ = false;
} else {
- setvbuf(stdout, NULL, _IONBF, 0);
console_ = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
smart_terminal_ = GetConsoleScreenBufferInfo(console_, &csbi);
diff --git a/src/ninja.cc b/src/ninja.cc
index 07b1f1e..3e5c971 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -1436,6 +1436,17 @@ NORETURN void real_main(int argc, char** argv) {
exit((ninja.*options.tool->func)(&options, argc, argv));
}
+#ifdef WIN32
+ // It'd be nice to use line buffering but MSDN says: "For some systems,
+ // [_IOLBF] provides line buffering. However, for Win32, the behavior is the
+ // same as _IOFBF - Full Buffering."
+ // Buffering used to be disabled in the LinePrinter constructor but that
+ // now disables it too early and breaks -t deps performance (see issue #2018)
+ // so we disable it here instead, but only when not running a tool.
+ if (!options.tool)
+ setvbuf(stdout, NULL, _IONBF, 0);
+#endif
+
// Limit number of rebuilds, to prevent infinite loops.
const int kCycleLimit = 100;
for (int cycle = 1; cycle <= kCycleLimit; ++cycle) {