From 3e917495ef2ec3b320b30baab6af029e8c7c5099 Mon Sep 17 00:00:00 2001 From: Benedek Thaler Date: Wed, 31 Jan 2024 08:59:41 +0100 Subject: [PATCH 1/2] Fix time handling On Linux platforms, where system_clock does not deal in nanoseconds. --- include/binlog/Time.hpp | 65 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/include/binlog/Time.hpp b/include/binlog/Time.hpp index af83041..d25d441 100644 --- a/include/binlog/Time.hpp +++ b/include/binlog/Time.hpp @@ -57,6 +57,36 @@ std::chrono::nanoseconds clockToNsSinceEpoch(const ClockSync& clockSync, std::ui */ void nsSinceEpochToBrokenDownTimeUTC(std::chrono::nanoseconds sinceEpoch, BrokenDownTime& dst); +/** Get the duration elapsed since the UNIX epoch in UTC (no leaps seconds) */ +inline + #ifdef __linux__ + std::chrono::nanoseconds + #else + std::chrono::system_clock::duration + #endif +clockSinceEpoch() +{ + // Depending on how libstdc++ is built (_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL), + // system_clock::now() can result in a clock_gettime syscall, + // which is really slow compared to the vsyscall equivalent. + // Call clock_gettime unconditionally on linux: + #ifdef __linux__ + struct timespec ts{}; + clock_gettime(CLOCK_REALTIME, &ts); + return std::chrono::nanoseconds{ + std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec} + }; + #else + return std::chrono::system_clock::now().time_since_epoch(); + #endif +} + +/** Get the number of clock ticks since the UNIX epoch in UTC (no leaps seconds) */ +inline std::uint64_t clockNow() +{ + return std::uint64_t(clockSinceEpoch().count()); +} + /** * Create a ClockSync corresponding to std::chrono::system_clock. * @@ -67,11 +97,10 @@ void nsSinceEpochToBrokenDownTimeUTC(std::chrono::nanoseconds sinceEpoch, Broken inline ClockSync systemClockSync() { using Clock = std::chrono::system_clock; - static_assert(Clock::period::num == 1, "Clock measures integer fractions of a second"); - const auto now = Clock::now(); - const auto since_epoch = now.time_since_epoch(); - const std::time_t now_tt = Clock::to_time_t(now); + const auto since_epoch = clockSinceEpoch(); + const auto now_tp = Clock::time_point(std::chrono::duration_cast(since_epoch)); + const std::time_t now_tt = Clock::to_time_t(now_tp); std::tm now_tm{}; #ifdef _WIN32 @@ -98,12 +127,9 @@ inline ClockSync systemClockSync() tzName[0] = 0; } - // on linux, clock_gettime is used directly - #ifdef __linux__ - const uint64_t frequency = 1'000'000'000; // nanoseconds - #else - const uint64_t frequency = std::uint64_t(Clock::period::den); - #endif + using Period = decltype(since_epoch)::period; + static_assert(Period::num == 1, "Clock measures integer fractions of a second"); + const uint64_t frequency = std::uint64_t(Period::den); return ClockSync{ std::uint64_t(since_epoch.count()), @@ -114,25 +140,6 @@ inline ClockSync systemClockSync() }; } -/** Get the number of nanoseconds since the UNIX epoch in UTC (no leaps seconds) */ -inline std::uint64_t clockNow() -{ - // Depending on how libstdc++ is built (_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL), - // system_clock::now() can result in a clock_gettime syscall, - // which is really slow compared to the vsyscall equivalent. - // Call clock_gettime unconditionally on linux: - #ifdef __linux__ - struct timespec ts{}; - clock_gettime(CLOCK_REALTIME, &ts); - const std::chrono::nanoseconds nanos{ - std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec} - }; - return std::uint64_t(nanos.count()); - #else - return std::uint64_t(std::chrono::system_clock::now().time_since_epoch().count()); - #endif -} - } // namespace binlog #endif // BINLOG_TIME_HPP From 536a5850893ff9a29f45a8697b6dd6b534533c2a Mon Sep 17 00:00:00 2001 From: Benedek Thaler Date: Thu, 22 Feb 2024 08:31:47 +0100 Subject: [PATCH 2/2] ci: Use clang with C++17 on Ubuntu Due to bug[0], on ubuntu, clang cannot #include with -std=c++20. Switch it to c++17, compile with c++20 on macOS. Alternative solution: install latest clang on ubuntu, but that takes much more time to run. [0]: https://github.com/actions/runner-images/issues/8659 --- .github/workflows/on_pull_request.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/on_pull_request.yml b/.github/workflows/on_pull_request.yml index c733161..27a0130 100644 --- a/.github/workflows/on_pull_request.yml +++ b/.github/workflows/on_pull_request.yml @@ -99,8 +99,8 @@ jobs: cd ThreadSanitized ctest -VV - build_linux_clang_cpp20: - name: Build on Linux with Clang, C++20 + build_linux_clang_cpp17: + name: Build on Linux with Clang, C++17 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -114,7 +114,7 @@ jobs: cd Clang export CC=$(which clang) export CXX=$(which clang++) - cmake -DCMAKE_CXX_STANDARD=20 .. + cmake -DCMAKE_CXX_STANDARD=17 .. - name: Build run: | cd Clang @@ -181,7 +181,7 @@ jobs: run: | mkdir Release cd Release - cmake -DCMAKE_CXX_STANDARD=17 .. + cmake -DCMAKE_CXX_STANDARD=20 .. make -j2 VERBOSE=1 - name: Test run: |