diff --git a/srtcore/sync.cpp b/srtcore/sync.cpp index 8f0c7c1c8..45d568212 100644 --- a/srtcore/sync.cpp +++ b/srtcore/sync.cpp @@ -34,26 +34,22 @@ std::string FormatTime(const steady_clock::time_point& timestamp) if (is_zero(timestamp)) { // Use special string for 0 - return "00:00:00.000000"; + return "00:00:00.000000 [STDY]"; } - const uint64_t total_us = count_microseconds(timestamp.time_since_epoch()); - const uint64_t us = total_us % 1000000; - const uint64_t total_sec = total_us / 1000000; - - const uint64_t days = total_sec / (60 * 60 * 24); + const int decimals = clockSubsecondPrecision(); + const uint64_t total_sec = count_seconds(timestamp.time_since_epoch()); + const uint64_t days = total_sec / (60 * 60 * 24); const uint64_t hours = total_sec / (60 * 60) - days * 24; - const uint64_t minutes = total_sec / 60 - (days * 24 * 60) - hours * 60; const uint64_t seconds = total_sec - (days * 24 * 60 * 60) - hours * 60 * 60 - minutes * 60; - ostringstream out; if (days) out << days << "D "; - out << setfill('0') << setw(2) << hours << ":" - << setfill('0') << setw(2) << minutes << ":" - << setfill('0') << setw(2) << seconds << "." - << setfill('0') << setw(6) << us << " [STD]"; + out << setfill('0') << setw(2) << hours << ":" + << setfill('0') << setw(2) << minutes << ":" + << setfill('0') << setw(2) << seconds << "." + << setfill('0') << setw(decimals) << timestamp.time_since_epoch().count() << " [STDY]"; return out.str(); } @@ -70,7 +66,7 @@ std::string FormatTimeSys(const steady_clock::time_point& timestamp) strftime(tmp_buf, 512, "%X.", &tm); ostringstream out; - out << tmp_buf << setfill('0') << setw(6) << (count_microseconds(timestamp.time_since_epoch()) % 1000000) << " [SYS]"; + out << tmp_buf << setfill('0') << setw(6) << (count_microseconds(timestamp.time_since_epoch()) % 1000000) << " [SYST]"; return out.str(); } diff --git a/srtcore/sync.h b/srtcore/sync.h index de739380c..59c125a75 100644 --- a/srtcore/sync.h +++ b/srtcore/sync.h @@ -217,6 +217,11 @@ inline Duration operator*(const int& lhs, const Duration +int pow10(); + +template <> +int pow10<10>() +{ + return 1; +} + +template +int pow10() +{ + return 1 + pow10(); +} +} + +int srt::sync::clockSubsecondPrecision() +{ + const int64_t ticks_per_sec = (srt::sync::steady_clock::period::den / srt::sync::steady_clock::period::num); + const int decimals = pow10(); + return decimals; +} + //////////////////////////////////////////////////////////////////////////////// // // SyncCond (based on stl chrono C++11) diff --git a/srtcore/sync_posix.cpp b/srtcore/sync_posix.cpp index 8c001ad62..d40e23713 100644 --- a/srtcore/sync_posix.cpp +++ b/srtcore/sync_posix.cpp @@ -114,8 +114,18 @@ int64_t get_cpu_frequency() return frequency; } -const int64_t s_cpu_frequency = get_cpu_frequency(); +static int count_subsecond_precision(int64_t ticks_per_us) +{ + int signs = 6; // starting from 1 us + while (ticks_per_us /= 10) ++signs; + return signs; +} + +const int64_t s_clock_ticks_per_us = get_cpu_frequency(); + +const int s_clock_subsecond_precision = count_subsecond_precision(s_clock_ticks_per_us); +int clockSubsecondPrecision() { return s_clock_subsecond_precision; } } // namespace sync } // namespace srt @@ -155,32 +165,32 @@ srt::sync::TimePoint srt::sync::steady_clock::now() int64_t srt::sync::count_microseconds(const steady_clock::duration& t) { - return t.count() / s_cpu_frequency; + return t.count() / s_clock_ticks_per_us; } int64_t srt::sync::count_milliseconds(const steady_clock::duration& t) { - return t.count() / s_cpu_frequency / 1000; + return t.count() / s_clock_ticks_per_us / 1000; } int64_t srt::sync::count_seconds(const steady_clock::duration& t) { - return t.count() / s_cpu_frequency / 1000000; + return t.count() / s_clock_ticks_per_us / 1000000; } srt::sync::steady_clock::duration srt::sync::microseconds_from(int64_t t_us) { - return steady_clock::duration(t_us * s_cpu_frequency); + return steady_clock::duration(t_us * s_clock_ticks_per_us); } srt::sync::steady_clock::duration srt::sync::milliseconds_from(int64_t t_ms) { - return steady_clock::duration((1000 * t_ms) * s_cpu_frequency); + return steady_clock::duration((1000 * t_ms) * s_clock_ticks_per_us); } srt::sync::steady_clock::duration srt::sync::seconds_from(int64_t t_s) { - return steady_clock::duration((1000000 * t_s) * s_cpu_frequency); + return steady_clock::duration((1000000 * t_s) * s_clock_ticks_per_us); } srt::sync::Mutex::Mutex() diff --git a/test/test_sync.cpp b/test/test_sync.cpp index 2a69c1980..713d190ff 100644 --- a/test/test_sync.cpp +++ b/test/test_sync.cpp @@ -586,7 +586,7 @@ TEST(Sync, FormatTime) { auto parse_time = [](const string& timestr) -> long long { // Example string: 1D 02:10:55.972651 [STD] - const regex rex("([[:digit:]]+D )?([[:digit:]]{2}):([[:digit:]]{2}):([[:digit:]]{2}).([[:digit:]]{6}) \\[STD\\]"); + const regex rex("([[:digit:]]+D )?([[:digit:]]{2}):([[:digit:]]{2}):([[:digit:]]{2}).([[:digit:]]{6,}) \\[STDY\\]"); std::smatch sm; EXPECT_TRUE(regex_match(timestr, sm, rex)); EXPECT_LE(sm.size(), 6); @@ -595,10 +595,10 @@ TEST(Sync, FormatTime) // Day may be missing if zero const long long d = sm[1].matched ? std::stoi(sm[1]) : 0; - const long long h = std::stoi(sm[2]); - const long long m = std::stoi(sm[3]); - const long long s = std::stoi(sm[4]); - const long long u = std::stoi(sm[5]); + const long long h = std::stoll(sm[2]); + const long long m = std::stoll(sm[3]); + const long long s = std::stoll(sm[4]); + const long long u = std::stoll(sm[5]); return u + s * 1000000 + m * 60000000 + h * 60 * 60 * 1000000 + d * 24 * 60 * 60 * 1000000; }; @@ -630,7 +630,7 @@ TEST(Sync, FormatTime) TEST(Sync, FormatTimeSys) { auto parse_time = [](const string& timestr) -> long long { - const regex rex("([[:digit:]]{2}):([[:digit:]]{2}):([[:digit:]]{2}).([[:digit:]]{6}) \\[SYS\\]"); + const regex rex("([[:digit:]]{2}):([[:digit:]]{2}):([[:digit:]]{2}).([[:digit:]]{6}) \\[SYST\\]"); std::smatch sm; EXPECT_TRUE(regex_match(timestr, sm, rex)); EXPECT_EQ(sm.size(), 5);