Skip to content

Commit

Permalink
[core] Increased FormatTime precision (#1766)
Browse files Browse the repository at this point in the history
Changed clock suffixes STD -> STDY, SYS -> SYST
  • Loading branch information
maxsharabayko committed Jan 29, 2021
1 parent 0d0888a commit 74fc74a
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 28 deletions.
22 changes: 9 additions & 13 deletions srtcore/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand All @@ -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();
}

Expand Down
9 changes: 7 additions & 2 deletions srtcore/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ inline Duration<steady_clock> operator*(const int& lhs, const Duration<steady_cl
//
///////////////////////////////////////////////////////////////////////////////

/// Function return number of decimals in a subsecond precision.
/// E.g. for a microsecond accuracy of steady_clock the return would be 6.
/// For a nanosecond accuracy of the steady_clock the return value would be 9.
int clockSubsecondPrecision();

#if ENABLE_STDCXX_SYNC

inline long long count_microseconds(const steady_clock::duration &t)
Expand Down Expand Up @@ -620,15 +625,15 @@ class CTimer


/// Print steady clock timepoint in a human readable way.
/// days HH:MM::SS.us [STD]
/// days HH:MM:SS.us [STD]
/// Example: 1D 02:12:56.123456
///
/// @param [in] steady clock timepoint
/// @returns a string with a formatted time representation
std::string FormatTime(const steady_clock::time_point& time);

/// Print steady clock timepoint relative to the current system time
/// Date HH:MM::SS.us [SYS]
/// Date HH:MM:SS.us [SYS]
/// @param [in] steady clock timepoint
/// @returns a string with a formatted time representation
std::string FormatTimeSys(const steady_clock::time_point& time);
Expand Down
30 changes: 30 additions & 0 deletions srtcore/sync_cxx11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,36 @@
#include "srt_compat.h"
#include "common.h"

////////////////////////////////////////////////////////////////////////////////
//
// Clock frequency helpers
//
////////////////////////////////////////////////////////////////////////////////

namespace {
template <int val>
int pow10();

template <>
int pow10<10>()
{
return 1;
}

template <int val>
int pow10()
{
return 1 + pow10<val / 10>();
}
}

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<ticks_per_sec>();
return decimals;
}

////////////////////////////////////////////////////////////////////////////////
//
// SyncCond (based on stl chrono C++11)
Expand Down
24 changes: 17 additions & 7 deletions srtcore/sync_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -155,32 +165,32 @@ srt::sync::TimePoint<srt::sync::steady_clock> 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()
Expand Down
12 changes: 6 additions & 6 deletions test/test_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
};
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 74fc74a

Please sign in to comment.