You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.9 KiB
206 lines
5.9 KiB
// 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
|
|
|