From: Adam C. Emerson Date: Tue, 15 Sep 2020 15:16:53 +0000 (-0400) Subject: common/ceph_time: Don't indent under namespaces X-Git-Tag: wip-pdonnell-testing-20200918.022351~18^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d94f2268a366c3aa07ca3437e238d5e2c49c8d58;p=ceph-ci.git common/ceph_time: Don't indent under namespaces This is a violation of our guidelines and since I'm making a larger change anyway. Signed-off-by: Adam C. Emerson --- diff --git a/src/common/ceph_time.cc b/src/common/ceph_time.cc index 1d3b0e1d6b7..f68cfd5a74c 100644 --- a/src/common/ceph_time.cc +++ b/src/common/ceph_time.cc @@ -55,276 +55,276 @@ int clock_gettime(int clk_id, struct timespec *tp) using namespace std::literals; namespace ceph { - namespace time_detail { - void real_clock::to_ceph_timespec(const time_point& t, - struct ceph_timespec& ts) { - ts.tv_sec = to_time_t(t); - ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); - } - struct ceph_timespec real_clock::to_ceph_timespec(const time_point& t) { - struct ceph_timespec ts; - to_ceph_timespec(t, ts); - return ts; - } - real_clock::time_point real_clock::from_ceph_timespec( - const struct ceph_timespec& ts) { - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } - - void coarse_real_clock::to_ceph_timespec(const time_point& t, - struct ceph_timespec& ts) { - ts.tv_sec = to_time_t(t); - ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); - } - struct ceph_timespec coarse_real_clock::to_ceph_timespec( - const time_point& t) { - struct ceph_timespec ts; - to_ceph_timespec(t, ts); - return ts; - } - coarse_real_clock::time_point coarse_real_clock::from_ceph_timespec( - const struct ceph_timespec& ts) { - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } +namespace time_detail { +void real_clock::to_ceph_timespec(const time_point& t, + struct ceph_timespec& ts) { + ts.tv_sec = to_time_t(t); + ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); +} +struct ceph_timespec real_clock::to_ceph_timespec(const time_point& t) { + struct ceph_timespec ts; + to_ceph_timespec(t, ts); + return ts; +} +real_clock::time_point real_clock::from_ceph_timespec( + const struct ceph_timespec& ts) { + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); +} - } +void coarse_real_clock::to_ceph_timespec(const time_point& t, + struct ceph_timespec& ts) { + ts.tv_sec = to_time_t(t); + ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); +} +struct ceph_timespec coarse_real_clock::to_ceph_timespec( + const time_point& t) { + struct ceph_timespec ts; + to_ceph_timespec(t, ts); + return ts; +} +coarse_real_clock::time_point coarse_real_clock::from_ceph_timespec( + const struct ceph_timespec& ts) { + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); +} - using std::chrono::duration_cast; - using std::chrono::seconds; - using std::chrono::microseconds; +} - template::type*> - std::ostream& operator<<(std::ostream& m, - const std::chrono::time_point& t) { - return m << std::fixed << std::chrono::duration( - t.time_since_epoch()).count() - << 's'; - } +using std::chrono::duration_cast; +using std::chrono::seconds; +using std::chrono::microseconds; - std::ostream& operator<<(std::ostream& m, const timespan& t) { - static_assert(std::is_unsigned_v); - m << std::chrono::duration_cast(t).count(); - if (auto ns = (t % 1s).count(); ns > 0) { - char oldfill = m.fill(); - m.fill('0'); - m << '.' << std::setw(9) << ns; - m.fill(oldfill); - } - return m << 's'; - } +template::type*> +std::ostream& operator<<(std::ostream& m, + const std::chrono::time_point& t) { + return m << std::fixed << std::chrono::duration( + t.time_since_epoch()).count() + << 's'; +} - template::type*> - std::ostream& operator<<(std::ostream& m, - const std::chrono::time_point& t) { - m.setf(std::ios::right); +std::ostream& operator<<(std::ostream& m, const timespan& t) { + static_assert(std::is_unsigned_v); + m << std::chrono::duration_cast(t).count(); + if (auto ns = (t % 1s).count(); ns > 0) { char oldfill = m.fill(); m.fill('0'); - // localtime. this looks like an absolute time. - // conform to http://en.wikipedia.org/wiki/ISO_8601 - struct tm bdt; - time_t tt = Clock::to_time_t(t); - localtime_r(&tt, &bdt); - char tz[32] = { 0 }; - strftime(tz, sizeof(tz), "%z", &bdt); - m << std::setw(4) << (bdt.tm_year+1900) // 2007 -> '07' - << '-' << std::setw(2) << (bdt.tm_mon+1) - << '-' << std::setw(2) << bdt.tm_mday - << 'T' - << std::setw(2) << bdt.tm_hour - << ':' << std::setw(2) << bdt.tm_min - << ':' << std::setw(2) << bdt.tm_sec - << "." << std::setw(6) << duration_cast( - t.time_since_epoch() % seconds(1)).count() - << tz; + m << '.' << std::setw(9) << ns; m.fill(oldfill); - m.unsetf(std::ios::right); - return m; } + return m << 's'; +} - template std::ostream& - operator<< (std::ostream& m, const mono_time& t); - template std::ostream& - operator<< (std::ostream& m, const real_time& t); - template std::ostream& - operator<< (std::ostream& m, const coarse_mono_time& t); - template std::ostream& - operator<< (std::ostream& m, const coarse_real_time& t); +template::type*> +std::ostream& operator<<(std::ostream& m, + const std::chrono::time_point& t) { + m.setf(std::ios::right); + char oldfill = m.fill(); + m.fill('0'); + // localtime. this looks like an absolute time. + // conform to http://en.wikipedia.org/wiki/ISO_8601 + struct tm bdt; + time_t tt = Clock::to_time_t(t); + localtime_r(&tt, &bdt); + char tz[32] = { 0 }; + strftime(tz, sizeof(tz), "%z", &bdt); + m << std::setw(4) << (bdt.tm_year+1900) // 2007 -> '07' + << '-' << std::setw(2) << (bdt.tm_mon+1) + << '-' << std::setw(2) << bdt.tm_mday + << 'T' + << std::setw(2) << bdt.tm_hour + << ':' << std::setw(2) << bdt.tm_min + << ':' << std::setw(2) << bdt.tm_sec + << "." << std::setw(6) << duration_cast( + t.time_since_epoch() % seconds(1)).count() + << tz; + m.fill(oldfill); + m.unsetf(std::ios::right); + return m; +} - std::string timespan_str(timespan t) - { - // FIXME: somebody pretty please make a version of this function - // that isn't as lame as this one! - uint64_t nsec = std::chrono::nanoseconds(t).count(); - std::ostringstream ss; - if (nsec < 2000000000) { - ss << ((float)nsec / 1000000000) << "s"; - return ss.str(); - } - uint64_t sec = nsec / 1000000000; - if (sec < 120) { - ss << sec << "s"; - return ss.str(); - } - uint64_t min = sec / 60; - if (min < 120) { - ss << min << "m"; - return ss.str(); - } - uint64_t hr = min / 60; - if (hr < 48) { - ss << hr << "h"; - return ss.str(); - } - uint64_t day = hr / 24; - if (day < 14) { - ss << day << "d"; - return ss.str(); - } - uint64_t wk = day / 7; - if (wk < 12) { - ss << wk << "w"; - return ss.str(); - } - uint64_t mn = day / 30; - if (mn < 24) { - ss << mn << "M"; - return ss.str(); - } - uint64_t yr = day / 365; - ss << yr << "y"; +template std::ostream& +operator<< (std::ostream& m, const mono_time& t); +template std::ostream& +operator<< (std::ostream& m, const real_time& t); +template std::ostream& +operator<< (std::ostream& m, const coarse_mono_time& t); +template std::ostream& +operator<< (std::ostream& m, const coarse_real_time& t); + +std::string timespan_str(timespan t) +{ + // FIXME: somebody pretty please make a version of this function + // that isn't as lame as this one! + uint64_t nsec = std::chrono::nanoseconds(t).count(); + std::ostringstream ss; + if (nsec < 2000000000) { + ss << ((float)nsec / 1000000000) << "s"; + return ss.str(); + } + uint64_t sec = nsec / 1000000000; + if (sec < 120) { + ss << sec << "s"; + return ss.str(); + } + uint64_t min = sec / 60; + if (min < 120) { + ss << min << "m"; return ss.str(); } + uint64_t hr = min / 60; + if (hr < 48) { + ss << hr << "h"; + return ss.str(); + } + uint64_t day = hr / 24; + if (day < 14) { + ss << day << "d"; + return ss.str(); + } + uint64_t wk = day / 7; + if (wk < 12) { + ss << wk << "w"; + return ss.str(); + } + uint64_t mn = day / 30; + if (mn < 24) { + ss << mn << "M"; + return ss.str(); + } + uint64_t yr = day / 365; + ss << yr << "y"; + return ss.str(); +} - std::string exact_timespan_str(timespan t) - { - uint64_t nsec = std::chrono::nanoseconds(t).count(); - uint64_t sec = nsec / 1000000000; - nsec %= 1000000000; - uint64_t yr = sec / (60 * 60 * 24 * 365); - std::ostringstream ss; - if (yr) { - ss << yr << "y"; - sec -= yr * (60 * 60 * 24 * 365); - } - uint64_t mn = sec / (60 * 60 * 24 * 30); - if (mn >= 3) { - ss << mn << "mo"; - sec -= mn * (60 * 60 * 24 * 30); - } - uint64_t wk = sec / (60 * 60 * 24 * 7); - if (wk >= 2) { - ss << wk << "w"; - sec -= wk * (60 * 60 * 24 * 7); - } - uint64_t day = sec / (60 * 60 * 24); - if (day >= 2) { - ss << day << "d"; - sec -= day * (60 * 60 * 24); - } - uint64_t hr = sec / (60 * 60); - if (hr >= 2) { - ss << hr << "h"; - sec -= hr * (60 * 60); +std::string exact_timespan_str(timespan t) +{ + uint64_t nsec = std::chrono::nanoseconds(t).count(); + uint64_t sec = nsec / 1000000000; + nsec %= 1000000000; + uint64_t yr = sec / (60 * 60 * 24 * 365); + std::ostringstream ss; + if (yr) { + ss << yr << "y"; + sec -= yr * (60 * 60 * 24 * 365); + } + uint64_t mn = sec / (60 * 60 * 24 * 30); + if (mn >= 3) { + ss << mn << "mo"; + sec -= mn * (60 * 60 * 24 * 30); + } + uint64_t wk = sec / (60 * 60 * 24 * 7); + if (wk >= 2) { + ss << wk << "w"; + sec -= wk * (60 * 60 * 24 * 7); + } + uint64_t day = sec / (60 * 60 * 24); + if (day >= 2) { + ss << day << "d"; + sec -= day * (60 * 60 * 24); + } + uint64_t hr = sec / (60 * 60); + if (hr >= 2) { + ss << hr << "h"; + sec -= hr * (60 * 60); + } + uint64_t min = sec / 60; + if (min >= 2) { + ss << min << "m"; + sec -= min * 60; + } + if (sec) { + ss << sec; + } + if (nsec) { + ss << ((float)nsec / 1000000000); + } + if (sec || nsec) { + ss << "s"; + } + return ss.str(); +} + +std::chrono::seconds parse_timespan(const std::string& s) +{ + static std::map units = { + { "s", 1 }, + { "sec", 1 }, + { "second", 1 }, + { "seconds", 1 }, + { "m", 60 }, + { "min", 60 }, + { "minute", 60 }, + { "minutes", 60 }, + { "h", 60*60 }, + { "hr", 60*60 }, + { "hour", 60*60 }, + { "hours", 60*60 }, + { "d", 24*60*60 }, + { "day", 24*60*60 }, + { "days", 24*60*60 }, + { "w", 7*24*60*60 }, + { "wk", 7*24*60*60 }, + { "week", 7*24*60*60 }, + { "weeks", 7*24*60*60 }, + { "mo", 30*24*60*60 }, + { "month", 30*24*60*60 }, + { "months", 30*24*60*60 }, + { "y", 365*24*60*60 }, + { "yr", 365*24*60*60 }, + { "year", 365*24*60*60 }, + { "years", 365*24*60*60 }, + }; + + auto r = 0s; + auto pos = 0u; + while (pos < s.size()) { + // skip whitespace + while (std::isspace(s[pos])) { + ++pos; } - uint64_t min = sec / 60; - if (min >= 2) { - ss << min << "m"; - sec -= min * 60; + if (pos >= s.size()) { + break; } - if (sec) { - ss << sec; + + // consume any digits + auto val_start = pos; + while (std::isdigit(s[pos])) { + ++pos; } - if (nsec) { - ss << ((float)nsec / 1000000000); + if (val_start == pos) { + throw std::invalid_argument("expected digit"); } - if (sec || nsec) { - ss << "s"; + auto n = s.substr(val_start, pos - val_start); + std::string err; + auto val = strict_strtoll(n.c_str(), 10, &err); + if (err.size()) { + throw std::invalid_argument(err); } - return ss.str(); - } - - std::chrono::seconds parse_timespan(const std::string& s) - { - static std::map units = { - { "s", 1 }, - { "sec", 1 }, - { "second", 1 }, - { "seconds", 1 }, - { "m", 60 }, - { "min", 60 }, - { "minute", 60 }, - { "minutes", 60 }, - { "h", 60*60 }, - { "hr", 60*60 }, - { "hour", 60*60 }, - { "hours", 60*60 }, - { "d", 24*60*60 }, - { "day", 24*60*60 }, - { "days", 24*60*60 }, - { "w", 7*24*60*60 }, - { "wk", 7*24*60*60 }, - { "week", 7*24*60*60 }, - { "weeks", 7*24*60*60 }, - { "mo", 30*24*60*60 }, - { "month", 30*24*60*60 }, - { "months", 30*24*60*60 }, - { "y", 365*24*60*60 }, - { "yr", 365*24*60*60 }, - { "year", 365*24*60*60 }, - { "years", 365*24*60*60 }, - }; - - auto r = 0s; - auto pos = 0u; - while (pos < s.size()) { - // skip whitespace - while (std::isspace(s[pos])) { - ++pos; - } - if (pos >= s.size()) { - break; - } - // consume any digits - auto val_start = pos; - while (std::isdigit(s[pos])) { - ++pos; - } - if (val_start == pos) { - throw std::invalid_argument("expected digit"); - } - auto n = s.substr(val_start, pos - val_start); - std::string err; - auto val = strict_strtoll(n.c_str(), 10, &err); - if (err.size()) { - throw std::invalid_argument(err); - } - - // skip whitespace - while (std::isspace(s[pos])) { - ++pos; - } + // skip whitespace + while (std::isspace(s[pos])) { + ++pos; + } - // consume unit - auto unit_start = pos; - while (std::isalpha(s[pos])) { - ++pos; - } - if (unit_start != pos) { - auto unit = s.substr(unit_start, pos - unit_start); - auto p = units.find(unit); - if (p == units.end()) { - throw std::invalid_argument("unrecogized unit '"s + unit + "'"); - } - val *= p->second; - } else if (pos < s.size()) { - throw std::invalid_argument("unexpected trailing '"s + s.substr(pos) + "'"); + // consume unit + auto unit_start = pos; + while (std::isalpha(s[pos])) { + ++pos; + } + if (unit_start != pos) { + auto unit = s.substr(unit_start, pos - unit_start); + auto p = units.find(unit); + if (p == units.end()) { + throw std::invalid_argument("unrecogized unit '"s + unit + "'"); } - r += std::chrono::seconds(val); + val *= p->second; + } else if (pos < s.size()) { + throw std::invalid_argument("unexpected trailing '"s + s.substr(pos) + "'"); } - return r; + r += std::chrono::seconds(val); } + return r; +} } diff --git a/src/common/ceph_time.h b/src/common/ceph_time.h index 58b1550495d..091641f6377 100644 --- a/src/common/ceph_time.h +++ b/src/common/ceph_time.h @@ -35,449 +35,449 @@ int clock_gettime(int clk_id, struct timespec *tp); struct ceph_timespec; namespace ceph { - namespace time_detail { - using std::chrono::duration_cast; - using std::chrono::seconds; - using std::chrono::microseconds; - using std::chrono::nanoseconds; - // Currently we use a 64-bit count of nanoseconds. - - // We could, if we wished, use a struct holding a uint64_t count - // of seconds and a uint32_t count of nanoseconds. - - // At least this way we can change it to something else if we - // want. - typedef uint64_t rep; - - // A concrete duration, unsigned. The timespan Ceph thinks in. - typedef std::chrono::duration timespan; - - - // Like the above but signed. - typedef int64_t signed_rep; - - typedef std::chrono::duration signedspan; - - // We define our own clocks so we can have our choice of all time - // sources supported by the operating system. With the standard - // library the resolution and cost are unspecified. (For example, - // the libc++ system_clock class gives only microsecond - // resolution.) - - // One potential issue is that we should accept system_clock - // timepoints in user-facing APIs alongside (or instead of) - // ceph::real_clock times. - class real_clock { - public: - typedef timespan duration; - typedef duration::rep rep; - typedef duration::period period; - // The second template parameter defaults to the clock's duration - // type. - typedef std::chrono::time_point time_point; - static constexpr const bool is_steady = false; - - static time_point now() noexcept { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - return from_timespec(ts); - } - - static bool is_zero(const time_point& t) { - return (t == time_point::min()); - } - - static time_point zero() { - return time_point::min(); - } - - // Allow conversion to/from any clock with the same interface as - // std::chrono::system_clock) - template - static time_point to_system_time_point( - const std::chrono::time_point& t) { - return time_point(seconds(Clock::to_time_t(t)) + - duration_cast(t.time_since_epoch() % - seconds(1))); - } - template - static std::chrono::time_point to_system_time_point( - const time_point& t) { - return (Clock::from_time_t(to_time_t(t)) + - duration_cast(t.time_since_epoch() % seconds(1))); - } - - static time_t to_time_t(const time_point& t) noexcept { - return duration_cast(t.time_since_epoch()).count(); - } - static time_point from_time_t(const time_t& t) noexcept { - return time_point(seconds(t)); - } - - static void to_timespec(const time_point& t, struct timespec& ts) { - ts.tv_sec = to_time_t(t); - ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); - } - static struct timespec to_timespec(const time_point& t) { - struct timespec ts; - to_timespec(t, ts); - return ts; - } - static time_point from_timespec(const struct timespec& ts) { - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } - - static void to_ceph_timespec(const time_point& t, - struct ceph_timespec& ts); - static struct ceph_timespec to_ceph_timespec(const time_point& t); - static time_point from_ceph_timespec(const struct ceph_timespec& ts); - - static void to_timeval(const time_point& t, struct timeval& tv) { - tv.tv_sec = to_time_t(t); - tv.tv_usec = duration_cast(t.time_since_epoch() % - seconds(1)).count(); - } - static struct timeval to_timeval(const time_point& t) { - struct timeval tv; - to_timeval(t, tv); - return tv; - } - static time_point from_timeval(const struct timeval& tv) { - return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); - } - - static double to_double(const time_point& t) { - return std::chrono::duration(t.time_since_epoch()).count(); - } - static time_point from_double(const double d) { - return time_point(duration_cast( - std::chrono::duration(d))); - } - }; - - class coarse_real_clock { - public: - typedef timespan duration; - typedef duration::rep rep; - typedef duration::period period; - // The second template parameter defaults to the clock's duration - // type. - typedef std::chrono::time_point time_point; - static constexpr const bool is_steady = false; - - static time_point now() noexcept { - struct timespec ts; +namespace time_detail { +using std::chrono::duration_cast; +using std::chrono::seconds; +using std::chrono::microseconds; +using std::chrono::nanoseconds; +// Currently we use a 64-bit count of nanoseconds. + +// We could, if we wished, use a struct holding a uint64_t count +// of seconds and a uint32_t count of nanoseconds. + +// At least this way we can change it to something else if we +// want. +typedef uint64_t rep; + +// A concrete duration, unsigned. The timespan Ceph thinks in. +typedef std::chrono::duration timespan; + + +// Like the above but signed. +typedef int64_t signed_rep; + +typedef std::chrono::duration signedspan; + +// We define our own clocks so we can have our choice of all time +// sources supported by the operating system. With the standard +// library the resolution and cost are unspecified. (For example, +// the libc++ system_clock class gives only microsecond +// resolution.) + +// One potential issue is that we should accept system_clock +// timepoints in user-facing APIs alongside (or instead of) +// ceph::real_clock times. +class real_clock { +public: + typedef timespan duration; + typedef duration::rep rep; + typedef duration::period period; + // The second template parameter defaults to the clock's duration + // type. + typedef std::chrono::time_point time_point; + static constexpr const bool is_steady = false; + + static time_point now() noexcept { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return from_timespec(ts); + } + + static bool is_zero(const time_point& t) { + return (t == time_point::min()); + } + + static time_point zero() { + return time_point::min(); + } + + // Allow conversion to/from any clock with the same interface as + // std::chrono::system_clock) + template + static time_point to_system_time_point( + const std::chrono::time_point& t) { + return time_point(seconds(Clock::to_time_t(t)) + + duration_cast(t.time_since_epoch() % + seconds(1))); + } + template + static std::chrono::time_point to_system_time_point( + const time_point& t) { + return (Clock::from_time_t(to_time_t(t)) + + duration_cast(t.time_since_epoch() % seconds(1))); + } + + static time_t to_time_t(const time_point& t) noexcept { + return duration_cast(t.time_since_epoch()).count(); + } + static time_point from_time_t(const time_t& t) noexcept { + return time_point(seconds(t)); + } + + static void to_timespec(const time_point& t, struct timespec& ts) { + ts.tv_sec = to_time_t(t); + ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); + } + static struct timespec to_timespec(const time_point& t) { + struct timespec ts; + to_timespec(t, ts); + return ts; + } + static time_point from_timespec(const struct timespec& ts) { + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); + } + + static void to_ceph_timespec(const time_point& t, + struct ceph_timespec& ts); + static struct ceph_timespec to_ceph_timespec(const time_point& t); + static time_point from_ceph_timespec(const struct ceph_timespec& ts); + + static void to_timeval(const time_point& t, struct timeval& tv) { + tv.tv_sec = to_time_t(t); + tv.tv_usec = duration_cast(t.time_since_epoch() % + seconds(1)).count(); + } + static struct timeval to_timeval(const time_point& t) { + struct timeval tv; + to_timeval(t, tv); + return tv; + } + static time_point from_timeval(const struct timeval& tv) { + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); + } + + static double to_double(const time_point& t) { + return std::chrono::duration(t.time_since_epoch()).count(); + } + static time_point from_double(const double d) { + return time_point(duration_cast( + std::chrono::duration(d))); + } +}; + +class coarse_real_clock { +public: + typedef timespan duration; + typedef duration::rep rep; + typedef duration::period period; + // The second template parameter defaults to the clock's duration + // type. + typedef std::chrono::time_point time_point; + static constexpr const bool is_steady = false; + + static time_point now() noexcept { + struct timespec ts; #if defined(CLOCK_REALTIME_COARSE) - // Linux systems have _COARSE clocks. - clock_gettime(CLOCK_REALTIME_COARSE, &ts); + // Linux systems have _COARSE clocks. + clock_gettime(CLOCK_REALTIME_COARSE, &ts); #elif defined(CLOCK_REALTIME_FAST) - // BSD systems have _FAST clocks. - clock_gettime(CLOCK_REALTIME_FAST, &ts); + // BSD systems have _FAST clocks. + clock_gettime(CLOCK_REALTIME_FAST, &ts); #else - // And if we find neither, you may wish to consult your system's - // documentation. + // And if we find neither, you may wish to consult your system's + // documentation. #warning Falling back to CLOCK_REALTIME, may be slow. - clock_gettime(CLOCK_REALTIME, &ts); + clock_gettime(CLOCK_REALTIME, &ts); #endif - return from_timespec(ts); - } - - static bool is_zero(const time_point& t) { - return (t == time_point::min()); - } - - static time_point zero() { - return time_point::min(); - } - - static time_t to_time_t(const time_point& t) noexcept { - return duration_cast(t.time_since_epoch()).count(); - } - static time_point from_time_t(const time_t t) noexcept { - return time_point(seconds(t)); - } - - static void to_timespec(const time_point& t, struct timespec& ts) { - ts.tv_sec = to_time_t(t); - ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); - } - static struct timespec to_timespec(const time_point& t) { - struct timespec ts; - to_timespec(t, ts); - return ts; - } - static time_point from_timespec(const struct timespec& ts) { - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } - - static void to_ceph_timespec(const time_point& t, - struct ceph_timespec& ts); - static struct ceph_timespec to_ceph_timespec(const time_point& t); - static time_point from_ceph_timespec(const struct ceph_timespec& ts); - - static void to_timeval(const time_point& t, struct timeval& tv) { - tv.tv_sec = to_time_t(t); - tv.tv_usec = duration_cast(t.time_since_epoch() % - seconds(1)).count(); - } - static struct timeval to_timeval(const time_point& t) { - struct timeval tv; - to_timeval(t, tv); - return tv; - } - static time_point from_timeval(const struct timeval& tv) { - return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); - } - - static double to_double(const time_point& t) { - return std::chrono::duration(t.time_since_epoch()).count(); - } - static time_point from_double(const double d) { - return time_point(duration_cast( - std::chrono::duration(d))); - } - }; - - class mono_clock { - public: - typedef timespan duration; - typedef duration::rep rep; - typedef duration::period period; - typedef std::chrono::time_point time_point; - static constexpr const bool is_steady = true; - - static time_point now() noexcept { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } - - static bool is_zero(const time_point& t) { - return (t == time_point::min()); - } - - static time_point zero() { - return time_point::min(); - } - - // A monotonic clock's timepoints are only meaningful to the - // computer on which they were generated. Thus having an - // optional skew is meaningless. - }; - - class coarse_mono_clock { - public: - typedef timespan duration; - typedef duration::rep rep; - typedef duration::period period; - typedef std::chrono::time_point time_point; - static constexpr const bool is_steady = true; - - static time_point now() noexcept { - struct timespec ts; + return from_timespec(ts); + } + + static bool is_zero(const time_point& t) { + return (t == time_point::min()); + } + + static time_point zero() { + return time_point::min(); + } + + static time_t to_time_t(const time_point& t) noexcept { + return duration_cast(t.time_since_epoch()).count(); + } + static time_point from_time_t(const time_t t) noexcept { + return time_point(seconds(t)); + } + + static void to_timespec(const time_point& t, struct timespec& ts) { + ts.tv_sec = to_time_t(t); + ts.tv_nsec = (t.time_since_epoch() % seconds(1)).count(); + } + static struct timespec to_timespec(const time_point& t) { + struct timespec ts; + to_timespec(t, ts); + return ts; + } + static time_point from_timespec(const struct timespec& ts) { + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); + } + + static void to_ceph_timespec(const time_point& t, + struct ceph_timespec& ts); + static struct ceph_timespec to_ceph_timespec(const time_point& t); + static time_point from_ceph_timespec(const struct ceph_timespec& ts); + + static void to_timeval(const time_point& t, struct timeval& tv) { + tv.tv_sec = to_time_t(t); + tv.tv_usec = duration_cast(t.time_since_epoch() % + seconds(1)).count(); + } + static struct timeval to_timeval(const time_point& t) { + struct timeval tv; + to_timeval(t, tv); + return tv; + } + static time_point from_timeval(const struct timeval& tv) { + return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec)); + } + + static double to_double(const time_point& t) { + return std::chrono::duration(t.time_since_epoch()).count(); + } + static time_point from_double(const double d) { + return time_point(duration_cast( + std::chrono::duration(d))); + } +}; + +class mono_clock { +public: + typedef timespan duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point time_point; + static constexpr const bool is_steady = true; + + static time_point now() noexcept { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); + } + + static bool is_zero(const time_point& t) { + return (t == time_point::min()); + } + + static time_point zero() { + return time_point::min(); + } + + // A monotonic clock's timepoints are only meaningful to the + // computer on which they were generated. Thus having an + // optional skew is meaningless. +}; + +class coarse_mono_clock { +public: + typedef timespan duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point time_point; + static constexpr const bool is_steady = true; + + static time_point now() noexcept { + struct timespec ts; #if defined(CLOCK_MONOTONIC_COARSE) - // Linux systems have _COARSE clocks. - clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + // Linux systems have _COARSE clocks. + clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); #elif defined(CLOCK_MONOTONIC_FAST) - // BSD systems have _FAST clocks. - clock_gettime(CLOCK_MONOTONIC_FAST, &ts); + // BSD systems have _FAST clocks. + clock_gettime(CLOCK_MONOTONIC_FAST, &ts); #else - // And if we find neither, you may wish to consult your system's - // documentation. + // And if we find neither, you may wish to consult your system's + // documentation. #warning Falling back to CLOCK_MONOTONIC, may be slow. - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(CLOCK_MONOTONIC, &ts); #endif - return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); - } - - static bool is_zero(const time_point& t) { - return (t == time_point::min()); - } - - static time_point zero() { - return time_point::min(); - } - }; - - // So that our subtractions produce negative spans rather than - // arithmetic underflow. - namespace { - template - inline auto difference(std::chrono::duration minuend, - std::chrono::duration subtrahend) - -> typename std::common_type< - std::chrono::duration::type, - Period1>, - std::chrono::duration::type, - Period2> >::type { - // Foo. - using srep = - typename std::common_type< - std::chrono::duration::type, - Period1>, - std::chrono::duration::type, - Period2> >::type; - return srep(srep(minuend).count() - srep(subtrahend).count()); - } - - template - inline auto difference( - typename std::chrono::time_point minuend, - typename std::chrono::time_point subtrahend) - -> typename std::common_type< - std::chrono::duration::type, - typename Duration1::period>, - std::chrono::duration::type, - typename Duration2::period> >::type { - return difference(minuend.time_since_epoch(), - subtrahend.time_since_epoch()); - } - } - } // namespace time_detail + return time_point(seconds(ts.tv_sec) + nanoseconds(ts.tv_nsec)); + } + + static bool is_zero(const time_point& t) { + return (t == time_point::min()); + } + + static time_point zero() { + return time_point::min(); + } +}; + +// So that our subtractions produce negative spans rather than +// arithmetic underflow. +namespace { +template +inline auto difference(std::chrono::duration minuend, + std::chrono::duration subtrahend) + -> typename std::common_type< + std::chrono::duration::type, + Period1>, + std::chrono::duration::type, + Period2> >::type { + // Foo. + using srep = + typename std::common_type< + std::chrono::duration::type, + Period1>, + std::chrono::duration::type, + Period2> >::type; + return srep(srep(minuend).count() - srep(subtrahend).count()); +} + +template +inline auto difference( + typename std::chrono::time_point minuend, + typename std::chrono::time_point subtrahend) + -> typename std::common_type< + std::chrono::duration::type, + typename Duration1::period>, + std::chrono::duration::type, + typename Duration2::period> >::type { + return difference(minuend.time_since_epoch(), + subtrahend.time_since_epoch()); +} +} +} // namespace time_detail // duration is the concrete time representation for our code in the // case that we are only interested in durations between now and the // future. Using it means we don't have to have EVERY function that // deals with a duration be a template. We can do so for user-facing // APIs, however. - using time_detail::timespan; - - // Similar to the above but for durations that can specify - // differences between now and a time point in the past. - using time_detail::signedspan; - - // High-resolution real-time clock - using time_detail::real_clock; - - // Low-resolution but preusmably faster real-time clock - using time_detail::coarse_real_clock; - - - // High-resolution monotonic clock - using time_detail::mono_clock; - - // Low-resolution but, I would hope or there's no point, faster - // monotonic clock - using time_detail::coarse_mono_clock; - - // Please note that the coarse clocks are disjoint. You cannot - // subtract a real_clock timepoint from a coarse_real_clock - // timepoint as, from C++'s perspective, they are disjoint types. - - // This is not necessarily bad. If I sample a mono_clock and then a - // coarse_mono_clock, the coarse_mono_clock's time could potentially - // be previous to the mono_clock's time (just due to differing - // resolution) which would be Incorrect. - - // This is not horrible, though, since you can use an idiom like - // mono_clock::timepoint(coarsepoint.time_since_epoch()) to unwrap - // and rewrap if you know what you're doing. - - - // Actual wall-clock times - typedef real_clock::time_point real_time; - typedef coarse_real_clock::time_point coarse_real_time; - - // Monotonic times should never be serialized or communicated - // between machines, since they are incomparable. Thus we also don't - // make any provision for converting between - // std::chrono::steady_clock time and ceph::mono_clock time. - typedef mono_clock::time_point mono_time; - typedef coarse_mono_clock::time_point coarse_mono_time; - - template - auto floor(const std::chrono::duration& duration, - const std::chrono::duration& precision) -> - typename std::common_type, - std::chrono::duration >::type { - return duration - (duration % precision); - } - - template - auto ceil(const std::chrono::duration& duration, - const std::chrono::duration& precision) -> - typename std::common_type, - std::chrono::duration >::type { - auto tmod = duration % precision; - return duration - tmod + (tmod > tmod.zero() ? 1 : 0) * precision; - } - - template - auto floor(const std::chrono::time_point& timepoint, - const std::chrono::duration& precision) -> - std::chrono::time_point - >::type> { - return std::chrono::time_point< - Clock, typename std::common_type< - Duration, std::chrono::duration >::type>( - floor(timepoint.time_since_epoch(), precision)); - } - template - auto ceil(const std::chrono::time_point& timepoint, - const std::chrono::duration& precision) -> - std::chrono::time_point >::type> { - return std::chrono::time_point< - Clock, typename std::common_type< - Duration, std::chrono::duration >::type>( - ceil(timepoint.time_since_epoch(), precision)); - } - - namespace { - inline timespan make_timespan(const double d) { - return std::chrono::duration_cast( - std::chrono::duration(d)); - } - inline std::optional maybe_timespan(const double d) { - return d ? std::make_optional(make_timespan(d)) : std::nullopt; - } - } - - std::ostream& operator<<(std::ostream& m, const timespan& t); - template::type* = nullptr> - std::ostream& operator<<(std::ostream& m, - const std::chrono::time_point& t); - template::type* = nullptr> - std::ostream& operator<<(std::ostream& m, - const std::chrono::time_point& t); - - // The way std::chrono handles the return type of subtraction is not - // wonderful. The difference of two unsigned types SHOULD be signed. - - namespace { - inline signedspan operator -(real_time minuend, - real_time subtrahend) { - return time_detail::difference(minuend, subtrahend); - } - - inline signedspan operator -(coarse_real_time minuend, - coarse_real_time subtrahend) { - return time_detail::difference(minuend, subtrahend); - } - - inline signedspan operator -(mono_time minuend, - mono_time subtrahend) { - return time_detail::difference(minuend, subtrahend); - } - - inline signedspan operator -(coarse_mono_time minuend, - coarse_mono_time subtrahend) { - return time_detail::difference(minuend, subtrahend); - } - } - - // We could add specializations of time_point - duration and - // time_point + duration to assert on overflow, but I don't think we - // should. +using time_detail::timespan; + +// Similar to the above but for durations that can specify +// differences between now and a time point in the past. +using time_detail::signedspan; + +// High-resolution real-time clock +using time_detail::real_clock; + +// Low-resolution but preusmably faster real-time clock +using time_detail::coarse_real_clock; + + +// High-resolution monotonic clock +using time_detail::mono_clock; + +// Low-resolution but, I would hope or there's no point, faster +// monotonic clock +using time_detail::coarse_mono_clock; + +// Please note that the coarse clocks are disjoint. You cannot +// subtract a real_clock timepoint from a coarse_real_clock +// timepoint as, from C++'s perspective, they are disjoint types. + +// This is not necessarily bad. If I sample a mono_clock and then a +// coarse_mono_clock, the coarse_mono_clock's time could potentially +// be previous to the mono_clock's time (just due to differing +// resolution) which would be Incorrect. + +// This is not horrible, though, since you can use an idiom like +// mono_clock::timepoint(coarsepoint.time_since_epoch()) to unwrap +// and rewrap if you know what you're doing. + + +// Actual wall-clock times +typedef real_clock::time_point real_time; +typedef coarse_real_clock::time_point coarse_real_time; + +// Monotonic times should never be serialized or communicated +// between machines, since they are incomparable. Thus we also don't +// make any provision for converting between +// std::chrono::steady_clock time and ceph::mono_clock time. +typedef mono_clock::time_point mono_time; +typedef coarse_mono_clock::time_point coarse_mono_time; + +template +auto floor(const std::chrono::duration& duration, + const std::chrono::duration& precision) -> + typename std::common_type, + std::chrono::duration >::type { + return duration - (duration % precision); +} + +template +auto ceil(const std::chrono::duration& duration, + const std::chrono::duration& precision) -> + typename std::common_type, + std::chrono::duration >::type { + auto tmod = duration % precision; + return duration - tmod + (tmod > tmod.zero() ? 1 : 0) * precision; +} + +template +auto floor(const std::chrono::time_point& timepoint, + const std::chrono::duration& precision) -> + std::chrono::time_point + >::type> { + return std::chrono::time_point< + Clock, typename std::common_type< + Duration, std::chrono::duration >::type>( + floor(timepoint.time_since_epoch(), precision)); +} +template +auto ceil(const std::chrono::time_point& timepoint, + const std::chrono::duration& precision) -> + std::chrono::time_point >::type> { + return std::chrono::time_point< + Clock, typename std::common_type< + Duration, std::chrono::duration >::type>( + ceil(timepoint.time_since_epoch(), precision)); +} + +namespace { +inline timespan make_timespan(const double d) { + return std::chrono::duration_cast( + std::chrono::duration(d)); +} +inline std::optional maybe_timespan(const double d) { + return d ? std::make_optional(make_timespan(d)) : std::nullopt; +} +} + +std::ostream& operator<<(std::ostream& m, const timespan& t); +template::type* = nullptr> +std::ostream& operator<<(std::ostream& m, + const std::chrono::time_point& t); +template::type* = nullptr> +std::ostream& operator<<(std::ostream& m, + const std::chrono::time_point& t); + +// The way std::chrono handles the return type of subtraction is not +// wonderful. The difference of two unsigned types SHOULD be signed. + +namespace { +inline signedspan operator -(real_time minuend, + real_time subtrahend) { + return time_detail::difference(minuend, subtrahend); +} + +inline signedspan operator -(coarse_real_time minuend, + coarse_real_time subtrahend) { + return time_detail::difference(minuend, subtrahend); +} + +inline signedspan operator -(mono_time minuend, + mono_time subtrahend) { + return time_detail::difference(minuend, subtrahend); +} + +inline signedspan operator -(coarse_mono_time minuend, + coarse_mono_time subtrahend) { + return time_detail::difference(minuend, subtrahend); +} +} + +// We could add specializations of time_point - duration and +// time_point + duration to assert on overflow, but I don't think we +// should. inline timespan abs(signedspan z) { @@ -512,8 +512,8 @@ struct converts_to_timespec : std::false_type {}; template struct converts_to_timespec())) + Clock::from_timespec(Clock::to_timespec( + std::declval())) )>> : std::true_type {}; template