diff options
author | Bruce Dawson <brucedawson@chromium.org> | 2021-10-01 14:39:03 -0700 |
---|---|---|
committer | Bruce Dawson <brucedawson@chromium.org> | 2021-10-01 14:39:29 -0700 |
commit | 95d7e865a15e22e516ce7cc681a7f801d6650cfb (patch) | |
tree | cdc87d4b494fd788bf80fbbaac7840ceedcf728b | |
parent | b337bbfd57172b8222048848feabc911af107d1a (diff) | |
download | ninja-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.cc | 5 | ||||
-rw-r--r-- | src/ninja.cc | 11 |
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) { |