123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- #pragma once
- #include <chrono>
- #include <cstdint>
- #include "opentelemetry/version.h"
- OPENTELEMETRY_BEGIN_NAMESPACE
- namespace common
- {
- /**
- * @brief A timepoint relative to the system clock epoch.
- *
- * This is used for marking the beginning and end of an operation.
- */
- class SystemTimestamp
- {
- public:
- /**
- * @brief Initializes a system timestamp pointing to the start of the epoch.
- */
- SystemTimestamp() noexcept : nanos_since_epoch_{0} {}
- /**
- * @brief Initializes a system timestamp from a duration.
- *
- * @param time_since_epoch Time elapsed since the beginning of the epoch.
- */
- template <class Rep, class Period>
- explicit SystemTimestamp(const std::chrono::duration<Rep, Period> &time_since_epoch) noexcept
- : nanos_since_epoch_{static_cast<int64_t>(
- std::chrono::duration_cast<std::chrono::nanoseconds>(time_since_epoch).count())}
- {}
- /**
- * @brief Initializes a system timestamp based on a point in time.
- *
- * @param time_point A point in time.
- */
- /*implicit*/ SystemTimestamp(const std::chrono::system_clock::time_point &time_point) noexcept
- : SystemTimestamp{time_point.time_since_epoch()}
- {}
- /**
- * @brief Returns a time point for the time stamp.
- *
- * @return A time point corresponding to the time stamp.
- */
- operator std::chrono::system_clock::time_point() const noexcept
- {
- return std::chrono::system_clock::time_point{
- std::chrono::duration_cast<std::chrono::system_clock::duration>(
- std::chrono::nanoseconds{nanos_since_epoch_})};
- }
- /**
- * @brief Returns the nanoseconds since the beginning of the epoch.
- *
- * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp.
- */
- std::chrono::nanoseconds time_since_epoch() const noexcept
- {
- return std::chrono::nanoseconds{nanos_since_epoch_};
- }
- /**
- * @brief Compare two steady time stamps.
- *
- * @return true if the two time stamps are equal.
- */
- bool operator==(const SystemTimestamp &other) const noexcept
- {
- return nanos_since_epoch_ == other.nanos_since_epoch_;
- }
- /**
- * @brief Compare two steady time stamps for inequality.
- *
- * @return true if the two time stamps are not equal.
- */
- bool operator!=(const SystemTimestamp &other) const noexcept
- {
- return nanos_since_epoch_ != other.nanos_since_epoch_;
- }
- private:
- int64_t nanos_since_epoch_;
- };
- /**
- * @brief A timepoint relative to the monotonic clock epoch
- *
- * This is used for calculating the duration of an operation.
- */
- class SteadyTimestamp
- {
- public:
- /**
- * @brief Initializes a monotonic timestamp pointing to the start of the epoch.
- */
- SteadyTimestamp() noexcept : nanos_since_epoch_{0} {}
- /**
- * @brief Initializes a monotonic timestamp from a duration.
- *
- * @param time_since_epoch Time elapsed since the beginning of the epoch.
- */
- template <class Rep, class Period>
- explicit SteadyTimestamp(const std::chrono::duration<Rep, Period> &time_since_epoch) noexcept
- : nanos_since_epoch_{static_cast<int64_t>(
- std::chrono::duration_cast<std::chrono::nanoseconds>(time_since_epoch).count())}
- {}
- /**
- * @brief Initializes a monotonic timestamp based on a point in time.
- *
- * @param time_point A point in time.
- */
- /*implicit*/ SteadyTimestamp(const std::chrono::steady_clock::time_point &time_point) noexcept
- : SteadyTimestamp{time_point.time_since_epoch()}
- {}
- /**
- * @brief Returns a time point for the time stamp.
- *
- * @return A time point corresponding to the time stamp.
- */
- operator std::chrono::steady_clock::time_point() const noexcept
- {
- return std::chrono::steady_clock::time_point{
- std::chrono::duration_cast<std::chrono::steady_clock::duration>(
- std::chrono::nanoseconds{nanos_since_epoch_})};
- }
- /**
- * @brief Returns the nanoseconds since the beginning of the epoch.
- *
- * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp.
- */
- std::chrono::nanoseconds time_since_epoch() const noexcept
- {
- return std::chrono::nanoseconds{nanos_since_epoch_};
- }
- /**
- * @brief Compare two steady time stamps.
- *
- * @return true if the two time stamps are equal.
- */
- bool operator==(const SteadyTimestamp &other) const noexcept
- {
- return nanos_since_epoch_ == other.nanos_since_epoch_;
- }
- /**
- * @brief Compare two steady time stamps for inequality.
- *
- * @return true if the two time stamps are not equal.
- */
- bool operator!=(const SteadyTimestamp &other) const noexcept
- {
- return nanos_since_epoch_ != other.nanos_since_epoch_;
- }
- private:
- int64_t nanos_since_epoch_;
- };
- class DurationUtil
- {
- public:
- template <class Rep, class Period>
- static std::chrono::duration<Rep, Period> AdjustWaitForTimeout(
- std::chrono::duration<Rep, Period> timeout,
- std::chrono::duration<Rep, Period> indefinite_value) noexcept
- {
- // Do not call now() when this duration is max value, now() may have a expensive cost.
- if (timeout == (std::chrono::duration<Rep, Period>::max)())
- {
- return indefinite_value;
- }
- // std::future<T>::wait_for, std::this_thread::sleep_for, and std::condition_variable::wait_for
- // may use steady_clock or system_clock.We need make sure now() + timeout do not overflow.
- auto max_timeout = std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
- (std::chrono::steady_clock::time_point::max)() - std::chrono::steady_clock::now());
- if (timeout >= max_timeout)
- {
- return indefinite_value;
- }
- max_timeout = std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(
- (std::chrono::system_clock::time_point::max)() - std::chrono::system_clock::now());
- if (timeout >= max_timeout)
- {
- return indefinite_value;
- }
- return timeout;
- }
- };
- } // namespace common
- OPENTELEMETRY_END_NAMESPACE
|