From 72f191288dfe29b70923b41a71bb41f610cb9437 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Fri, 27 Aug 2021 16:38:21 -0700 Subject: Make ScopedMetric portable, accurate, and efficient ScopedMetric used to use separate code paths for Win32 and other platforms. std::chrono makes it practical to use the same code everywhere. This requires C++ 11 so that is specified in the configuration file (C++ 11 was already used on Win32 builds). This change also makes ScopedMetric more accurate because it postpones converting the raw deltas until it is time to report them. Previously they would be converted at each measurement site, potentially losing almost a microsecond each time. Postponing the conversion also reduces the cost of ScopedMetric. The performance of std::chrono is currently harmed a bit by some design and code-gen issues in VC++, but bugs have been filed and these should be fixed. The overhead is low enough to be inconsequential for the O(15,000) ScopedMetric objects created in a build of Chrome. The net result is that the ScopedMetric code is now portable, more accurate, and as fast or faster than it used to be. This will resolve issue #2004. --- CMakeLists.txt | 1 + src/metrics.cc | 66 ++++++++++++++++++++++++---------------------------------- src/metrics.h | 12 +++++------ 3 files changed, 34 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b49c5b0..234724d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ else() endif() # --- compiler flags +set(CMAKE_CXX_STANDARD 11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/src/metrics.cc b/src/metrics.cc index dbaf221..caad696 100644 --- a/src/metrics.cc +++ b/src/metrics.cc @@ -18,13 +18,8 @@ #include #include -#ifndef _WIN32 -#include -#else -#include -#endif - #include +#include #include "util.h" @@ -34,45 +29,30 @@ Metrics* g_metrics = NULL; namespace { -#ifndef _WIN32 /// Compute a platform-specific high-res timer value that fits into an int64. int64_t HighResTimer() { - timeval tv; - if (gettimeofday(&tv, NULL) < 0) - Fatal("gettimeofday: %s", strerror(errno)); - return (int64_t)tv.tv_sec * 1000*1000 + tv.tv_usec; + auto now = chrono::steady_clock::now(); + return chrono::duration_cast(now.time_since_epoch()).count(); } -/// Convert a delta of HighResTimer() values to microseconds. -int64_t TimerToMicros(int64_t dt) { - // No conversion necessary. - return dt; -} -#else -int64_t LargeIntegerToInt64(const LARGE_INTEGER& i) { - return ((int64_t)i.HighPart) << 32 | i.LowPart; -} +constexpr int64_t GetFrequency() { + constexpr auto den = std::chrono::steady_clock::period::den; + constexpr auto num = std::chrono::steady_clock::period::num; -int64_t HighResTimer() { - LARGE_INTEGER counter; - if (!QueryPerformanceCounter(&counter)) - Fatal("QueryPerformanceCounter: %s", GetLastErrorString().c_str()); - return LargeIntegerToInt64(counter); + // If numerator isn't 1 then we lose precision and that will need to be assessed. + static_assert(num == 1, "Numerator must be 1"); + return den / num; } int64_t TimerToMicros(int64_t dt) { - static int64_t ticks_per_sec = 0; - if (!ticks_per_sec) { - LARGE_INTEGER freq; - if (!QueryPerformanceFrequency(&freq)) - Fatal("QueryPerformanceFrequency: %s", GetLastErrorString().c_str()); - ticks_per_sec = LargeIntegerToInt64(freq); - } + // dt is in ticks. We want microseconds. + return (dt * 1000000) / GetFrequency(); +} +int64_t TimerToMicros(double dt) { // dt is in ticks. We want microseconds. - return (dt * 1000000) / ticks_per_sec; + return (dt * 1000000) / GetFrequency(); } -#endif } // anonymous namespace @@ -87,7 +67,9 @@ ScopedMetric::~ScopedMetric() { if (!metric_) return; metric_->count++; - int64_t dt = TimerToMicros(HighResTimer() - start_); + // Leave in the timer's natural frequency to avoid paying the conversion cost on + // every measurement. + int64_t dt = HighResTimer() - start_; metric_->sum += dt; } @@ -112,15 +94,21 @@ void Metrics::Report() { for (vector::iterator i = metrics_.begin(); i != metrics_.end(); ++i) { Metric* metric = *i; - double total = metric->sum / (double)1000; - double avg = metric->sum / (double)metric->count; + uint64_t micros = TimerToMicros(metric->sum); + double total = micros / (double)1000; + double avg = micros / (double)metric->count; printf("%-*s\t%-6d\t%-8.1f\t%.1f\n", width, metric->name.c_str(), metric->count, avg, total); } } -uint64_t Stopwatch::Now() const { - return TimerToMicros(HighResTimer()); +double Stopwatch::Elapsed() const { + // Convert to micros after converting to double to minimize error. + return 1e-6 * TimerToMicros(static_cast(NowRaw() - started_)); +} + +uint64_t Stopwatch::NowRaw() const { + return HighResTimer(); } int64_t GetTimeMillis() { diff --git a/src/metrics.h b/src/metrics.h index 11239b5..549e935 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -28,7 +28,7 @@ struct Metric { std::string name; /// Number of times we've hit the code path. int count; - /// Total time (in micros) we've spent on the code path. + /// Total time (in platform-dependent units) we've spent on the code path. int64_t sum; }; @@ -68,15 +68,15 @@ struct Stopwatch { Stopwatch() : started_(0) {} /// Seconds since Restart() call. - double Elapsed() const { - return 1e-6 * static_cast(Now() - started_); - } + double Elapsed() const; - void Restart() { started_ = Now(); } + void Restart() { started_ = NowRaw(); } private: uint64_t started_; - uint64_t Now() const; + // Return the current time using the native frequency of the high resolution + // timer. + uint64_t NowRaw() const; }; /// The primary interface to metrics. Use METRIC_RECORD("foobar") at the top -- cgit v1.2.1 From 04170ad365a64caba3f10fbc5e63714ff4c4ad5b Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Fri, 27 Aug 2021 17:02:20 -0700 Subject: Fix constexpr and clang-format --- CONTRIBUTING.md | 2 +- src/metrics.cc | 22 +++++++++++----------- src/metrics.h | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be1fc02..0e24dfd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ Generally it's the a few additions: * Any code merged into the Ninja codebase which will be part of the main - executable must compile as C++03. You may use C++11 features in a test or an + executable must compile as C++11. You may use C++14 features in a test or an unimportant tool if you guard your code with `#if __cplusplus >= 201103L`. * We have used `using namespace std;` a lot in the past. For new contributions, please try to avoid relying on it and instead whenever possible use `std::`. diff --git a/src/metrics.cc b/src/metrics.cc index caad696..9a4dd12 100644 --- a/src/metrics.cc +++ b/src/metrics.cc @@ -32,16 +32,18 @@ namespace { /// Compute a platform-specific high-res timer value that fits into an int64. int64_t HighResTimer() { auto now = chrono::steady_clock::now(); - return chrono::duration_cast(now.time_since_epoch()).count(); + return chrono::duration_cast( + now.time_since_epoch()) + .count(); } constexpr int64_t GetFrequency() { - constexpr auto den = std::chrono::steady_clock::period::den; - constexpr auto num = std::chrono::steady_clock::period::num; - - // If numerator isn't 1 then we lose precision and that will need to be assessed. - static_assert(num == 1, "Numerator must be 1"); - return den / num; + // If numerator isn't 1 then we lose precision and that will need to be + // assessed. + static_assert(std::chrono::steady_clock::period::num == 1, + "Numerator must be 1"); + return std::chrono::steady_clock::period::den / + std::chrono::steady_clock::period::num; } int64_t TimerToMicros(int64_t dt) { @@ -56,7 +58,6 @@ int64_t TimerToMicros(double dt) { } // anonymous namespace - ScopedMetric::ScopedMetric(Metric* metric) { metric_ = metric; if (!metric_) @@ -67,8 +68,8 @@ ScopedMetric::~ScopedMetric() { if (!metric_) return; metric_->count++; - // Leave in the timer's natural frequency to avoid paying the conversion cost on - // every measurement. + // Leave in the timer's natural frequency to avoid paying the conversion cost + // on every measurement. int64_t dt = HighResTimer() - start_; metric_->sum += dt; } @@ -114,4 +115,3 @@ uint64_t Stopwatch::NowRaw() const { int64_t GetTimeMillis() { return TimerToMicros(HighResTimer()) / 1000; } - diff --git a/src/metrics.h b/src/metrics.h index 549e935..c9ba236 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -32,7 +32,6 @@ struct Metric { int64_t sum; }; - /// A scoped object for recording a metric across the body of a function. /// Used by the METRIC_RECORD macro. struct ScopedMetric { -- cgit v1.2.1 From 1130200c2396c58f67831fccbd4eee4df196f696 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Sat, 28 Aug 2021 10:01:49 -0700 Subject: Update __cplusplus value --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e24dfd..69dac74 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ a few additions: * Any code merged into the Ninja codebase which will be part of the main executable must compile as C++11. You may use C++14 features in a test or an - unimportant tool if you guard your code with `#if __cplusplus >= 201103L`. + unimportant tool if you guard your code with `#if __cplusplus >= 201402L`. * We have used `using namespace std;` a lot in the past. For new contributions, please try to avoid relying on it and instead whenever possible use `std::`. However, please do not change existing code simply to add `std::` unless your -- cgit v1.2.1 From 40a57813bd9a2551d8377f085974074d1aefc6cb Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 15:01:50 -1000 Subject: Make chrono optional, and enable updated __cplusplus on MSVC --- CMakeLists.txt | 1 + configure.py | 3 ++- src/metrics.cc | 29 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f4e160..b9a8af6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(CMAKE_CXX_STANDARD 11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + # These settings seem to be completely ignored - see configure.py for the actual options. add_compile_options(/W4 /wd4100 /wd4267 /wd4706 /wd4702 /wd4244 /GR- /Zc:__cplusplus) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) else() diff --git a/configure.py b/configure.py index 4390434..0ff1716 100755 --- a/configure.py +++ b/configure.py @@ -325,7 +325,8 @@ if platform.is_msvc(): '/wd4267', '/DNOMINMAX', '/D_CRT_SECURE_NO_WARNINGS', '/D_HAS_EXCEPTIONS=0', - '/DNINJA_PYTHON="%s"' % options.with_python] + '/DNINJA_PYTHON="%s"' % options.with_python, + '/Zc:__cplusplus'] if platform.msvc_needs_fs(): cflags.append('/FS') ldflags = ['/DEBUG', '/libpath:$builddir'] diff --git a/src/metrics.cc b/src/metrics.cc index 9a4dd12..3b403a9 100644 --- a/src/metrics.cc +++ b/src/metrics.cc @@ -14,12 +14,22 @@ #include "metrics.h" +#if __cplusplus >= 201103L +// C++ 11 is not available on older Linux build machines. +#define USE_CHRONO +#endif + #include #include #include #include + +#if defined(USE_CHRONO) #include +#else +#include +#endif #include "util.h" @@ -31,12 +41,20 @@ namespace { /// Compute a platform-specific high-res timer value that fits into an int64. int64_t HighResTimer() { +#if defined(USE_CHRONO) auto now = chrono::steady_clock::now(); return chrono::duration_cast( now.time_since_epoch()) .count(); +#else + timeval tv; + if (gettimeofday(&tv, NULL) < 0) + Fatal("gettimeofday: %s", strerror(errno)); + return (int64_t)tv.tv_sec * 1000*1000 + tv.tv_usec; +#endif } +#if defined(USE_CHRONO) constexpr int64_t GetFrequency() { // If numerator isn't 1 then we lose precision and that will need to be // assessed. @@ -45,15 +63,26 @@ constexpr int64_t GetFrequency() { return std::chrono::steady_clock::period::den / std::chrono::steady_clock::period::num; } +#endif int64_t TimerToMicros(int64_t dt) { +#if defined(USE_CHRONO) // dt is in ticks. We want microseconds. return (dt * 1000000) / GetFrequency(); +#else + // No conversion necessary. + return dt; +#endif } int64_t TimerToMicros(double dt) { +#if defined(USE_CHRONO) // dt is in ticks. We want microseconds. return (dt * 1000000) / GetFrequency(); +#else + // No conversion necessary. + return dt; +#endif } } // anonymous namespace -- cgit v1.2.1 From 928151a5a2051f1b90386a8cc0960733a29c6b46 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 15:51:54 -1000 Subject: Enabling C++11 in configure.py --- CMakeLists.txt | 1 - configure.py | 1 + src/metrics.cc | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9a8af6..13c7152 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,6 @@ else() endif() # --- compiler flags -set(CMAKE_CXX_STANDARD 11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) diff --git a/configure.py b/configure.py index 0ff1716..4c81e5d 100755 --- a/configure.py +++ b/configure.py @@ -340,6 +340,7 @@ else: '-Wno-unused-parameter', '-fno-rtti', '-fno-exceptions', + '-std=c++11', '-fvisibility=hidden', '-pipe', '-DNINJA_PYTHON="%s"' % options.with_python] if options.debug: diff --git a/src/metrics.cc b/src/metrics.cc index 3b403a9..9b43883 100644 --- a/src/metrics.cc +++ b/src/metrics.cc @@ -28,6 +28,7 @@ #if defined(USE_CHRONO) #include #else +#error #include #endif -- cgit v1.2.1 From 809e67e5c333f2750909f9bcb21b405cf497deb3 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 16:03:16 -1000 Subject: Restore CMakeLists.txt change --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13c7152..b9a8af6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ else() endif() # --- compiler flags +set(CMAKE_CXX_STANDARD 11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -- cgit v1.2.1 From a35da107da8991aaaa3a441f5bce1234ead86f9f Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 17:00:31 -1000 Subject: Update CMake c++11 request per CR comment --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9a8af6..04e5c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ else() endif() # --- compiler flags -set(CMAKE_CXX_STANDARD 11) +target_compile_features(libninja PUBLIC cxx_std_11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -- cgit v1.2.1 From 34ec9f550db8b764f05aca39b8c306b946b8c9cd Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 17:06:57 -1000 Subject: libninja -> ninja --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04e5c34..125b21c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ else() endif() # --- compiler flags -target_compile_features(libninja PUBLIC cxx_std_11) +target_compile_features(ninja PUBLIC cxx_std_11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) -- cgit v1.2.1 From 01e7c50f508b47409f2554285237722f010d0720 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 17:12:39 -1000 Subject: Adjusting placement --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 125b21c..9e78188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,6 @@ else() endif() # --- compiler flags -target_compile_features(ninja PUBLIC cxx_std_11) if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) @@ -138,6 +137,8 @@ else() endif() endif() +target_compile_features(libninja PUBLIC cxx_std_11) + #Fixes GetActiveProcessorCount on MinGW if(MINGW) target_compile_definitions(libninja PRIVATE _WIN32_WINNT=0x0601 __USE_MINGW_ANSI_STDIO=1) -- cgit v1.2.1 From 65c82f4b99f29db594d6c65fee87f659d0cf94c0 Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Thu, 17 Feb 2022 18:51:53 -1000 Subject: Cleanup --- CMakeLists.txt | 3 ++- configure.py | 6 ++++-- src/metrics.cc | 30 ------------------------------ 3 files changed, 6 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e78188..69ce1ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,8 @@ endif() if(MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - # These settings seem to be completely ignored - see configure.py for the actual options. + # Note that these settings are separately specified in configure.py, and + # these lists should be kept in sync. add_compile_options(/W4 /wd4100 /wd4267 /wd4706 /wd4702 /wd4244 /GR- /Zc:__cplusplus) add_compile_definitions(_CRT_SECURE_NO_WARNINGS) else() diff --git a/configure.py b/configure.py index 4c81e5d..99a2c86 100755 --- a/configure.py +++ b/configure.py @@ -305,6 +305,8 @@ if platform.is_msvc(): else: n.variable('ar', configure_env.get('AR', 'ar')) +# Note that build settings are separately specified in CMakeLists.txt and +# these lists should be kept in sync. if platform.is_msvc(): cflags = ['/showIncludes', '/nologo', # Don't print startup banner. @@ -320,13 +322,13 @@ if platform.is_msvc(): # Disable warnings about ignored typedef in DbgHelp.h '/wd4091', '/GR-', # Disable RTTI. + '/Zc:__cplusplus', # Disable size_t -> int truncation warning. # We never have strings or arrays larger than 2**31. '/wd4267', '/DNOMINMAX', '/D_CRT_SECURE_NO_WARNINGS', '/D_HAS_EXCEPTIONS=0', - '/DNINJA_PYTHON="%s"' % options.with_python, - '/Zc:__cplusplus'] + '/DNINJA_PYTHON="%s"' % options.with_python] if platform.msvc_needs_fs(): cflags.append('/FS') ldflags = ['/DEBUG', '/libpath:$builddir'] diff --git a/src/metrics.cc b/src/metrics.cc index 9b43883..9a4dd12 100644 --- a/src/metrics.cc +++ b/src/metrics.cc @@ -14,23 +14,12 @@ #include "metrics.h" -#if __cplusplus >= 201103L -// C++ 11 is not available on older Linux build machines. -#define USE_CHRONO -#endif - #include #include #include #include - -#if defined(USE_CHRONO) #include -#else -#error -#include -#endif #include "util.h" @@ -42,20 +31,12 @@ namespace { /// Compute a platform-specific high-res timer value that fits into an int64. int64_t HighResTimer() { -#if defined(USE_CHRONO) auto now = chrono::steady_clock::now(); return chrono::duration_cast( now.time_since_epoch()) .count(); -#else - timeval tv; - if (gettimeofday(&tv, NULL) < 0) - Fatal("gettimeofday: %s", strerror(errno)); - return (int64_t)tv.tv_sec * 1000*1000 + tv.tv_usec; -#endif } -#if defined(USE_CHRONO) constexpr int64_t GetFrequency() { // If numerator isn't 1 then we lose precision and that will need to be // assessed. @@ -64,26 +45,15 @@ constexpr int64_t GetFrequency() { return std::chrono::steady_clock::period::den / std::chrono::steady_clock::period::num; } -#endif int64_t TimerToMicros(int64_t dt) { -#if defined(USE_CHRONO) // dt is in ticks. We want microseconds. return (dt * 1000000) / GetFrequency(); -#else - // No conversion necessary. - return dt; -#endif } int64_t TimerToMicros(double dt) { -#if defined(USE_CHRONO) // dt is in ticks. We want microseconds. return (dt * 1000000) / GetFrequency(); -#else - // No conversion necessary. - return dt; -#endif } } // anonymous namespace -- cgit v1.2.1 From 721f09bda72144ed1ab7257b6aa50eecc8abac8a Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Mon, 24 Oct 2022 16:36:07 -0700 Subject: Remove bad merge text from .md file --- CONTRIBUTING.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f003750..37f6ebc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,9 +14,6 @@ Generally it's the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) with a few additions: -* Any code merged into the Ninja codebase which will be part of the main - executable must compile as C++11. You may use C++14 features in a test or an - unimportant tool if you guard your code with `#if __cplusplus >= 201402L`. * We have used `using namespace std;` a lot in the past. For new contributions, please try to avoid relying on it and instead whenever possible use `std::`. However, please do not change existing code simply to add `std::` unless your -- cgit v1.2.1 From f5f7feaf21983f233ccc380ae95c79360cdb0bbc Mon Sep 17 00:00:00 2001 From: Bruce Dawson Date: Mon, 24 Oct 2022 19:36:44 -0700 Subject: Revert configure.py change --- configure.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 configure.py diff --git a/configure.py b/configure.py old mode 100644 new mode 100755 -- cgit v1.2.1