summaryrefslogtreecommitdiff
path: root/src/mongo/util/system_tick_source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util/system_tick_source.cpp')
-rw-r--r--src/mongo/util/system_tick_source.cpp136
1 files changed, 18 insertions, 118 deletions
diff --git a/src/mongo/util/system_tick_source.cpp b/src/mongo/util/system_tick_source.cpp
index ee5f24d4e83..293b072f079 100644
--- a/src/mongo/util/system_tick_source.cpp
+++ b/src/mongo/util/system_tick_source.cpp
@@ -27,132 +27,32 @@
* it in the license file.
*/
-#include "mongo/platform/basic.h"
-
#include "mongo/util/system_tick_source.h"
-#include "mongo/config.h"
-
-#include <ctime>
-#include <limits>
-#if defined(MONGO_CONFIG_HAVE_HEADER_UNISTD_H)
-#include <unistd.h>
-#endif
+#include <chrono> // NOLINT
#include <memory>
-#include "mongo/base/init.h"
-#include "mongo/util/assert_util.h"
#include "mongo/util/tick_source.h"
-#include "mongo/util/time_support.h"
namespace mongo {
-namespace {
-
-const int64_t kMillisPerSecond = 1000;
-const int64_t kMicrosPerSecond = 1000 * kMillisPerSecond;
-const int64_t kNanosPerSecond = 1000 * kMicrosPerSecond;
-
-/**
- * Internally, the timer counts platform-dependent ticks of some sort, and
- * must then convert those ticks to microseconds and their ilk. This field
- * stores the frequency of the platform-dependent counter.
- *
- * Define ticksPerSecond before init to ensure correct relative sequencing
- * regardless of how it is initialized (static or dynamic).
- */
-TickSource::Tick ticksPerSecond = kMicrosPerSecond;
-
-// "Generic" implementation for _timerNow.
-TickSource::Tick _timerNowGeneric() {
- return curTimeMicros64();
-}
-
-// Function pointer to timer implementation.
-// Overridden in initTickSource() with better implementation where available.
-TickSource::Tick (*_timerNow)() = &_timerNowGeneric;
-
-#if defined(_WIN32)
-
-/**
- * Windows-specific implementation of the
- * Timer class. Windows selects the best available timer, in its estimation, for
- * measuring time at high resolution. This may be the HPET of the TSC on x86 systems,
- * but is promised to be synchronized across processors, barring BIOS errors.
- */
-TickSource::Tick timerNowWindows() {
- LARGE_INTEGER i;
- fassert(16161, QueryPerformanceCounter(&i));
- return i.QuadPart;
-}
-
-void initTickSource() {
- LARGE_INTEGER x;
- bool ok = QueryPerformanceFrequency(&x);
- verify(ok);
- ticksPerSecond = x.QuadPart;
- _timerNow = &timerNowWindows;
-}
-
-#elif defined(MONGO_CONFIG_HAVE_POSIX_MONOTONIC_CLOCK)
-
-/**
- * Implementation for timer on systems that support the
- * POSIX clock API and CLOCK_MONOTONIC clock.
- */
-TickSource::Tick timerNowPosixMonotonicClock() {
- timespec the_time;
- long long result;
-
- fassert(16160, !clock_gettime(CLOCK_MONOTONIC, &the_time));
-
- // Safe for 292 years after the clock epoch, even if we switch to a signed time value.
- // On Linux, the monotonic clock's epoch is the UNIX epoch.
- result = static_cast<long long>(the_time.tv_sec);
- result *= kNanosPerSecond;
- result += static_cast<long long>(the_time.tv_nsec);
- return result;
-}
-
-void initTickSource() {
- // If the monotonic clock is not available at runtime (sysconf() returns 0 or -1),
- // do not override the generic implementation or modify ticksPerSecond.
- if (sysconf(_SC_MONOTONIC_CLOCK) <= 0) {
- return;
- }
-
- ticksPerSecond = kNanosPerSecond;
- _timerNow = &timerNowPosixMonotonicClock;
-
- // Make sure that the current time relative to the (unspecified) epoch isn't already too
- // big to represent as a 64-bit count of nanoseconds.
- long long maxSecs = std::numeric_limits<long long>::max() / kNanosPerSecond;
- timespec the_time;
- fassert(16162, !clock_gettime(CLOCK_MONOTONIC, &the_time));
- fassert(16163, static_cast<long long>(the_time.tv_sec) < maxSecs);
-}
-#else
-void initTickSource() {}
-#endif
-
-} // unnamed namespace
-
-MONGO_INITIALIZER(SystemTickSourceInit)(InitializerContext* context) {
- initTickSource();
- SystemTickSource::get();
-}
-
-TickSource::Tick SystemTickSource::getTicks() {
- return _timerNow();
-}
-
-TickSource::Tick SystemTickSource::getTicksPerSecond() {
- return ticksPerSecond;
-}
-
-SystemTickSource* SystemTickSource::get() {
- static const auto globalSystemTickSource = std::make_unique<SystemTickSource>();
- return globalSystemTickSource.get();
+std::unique_ptr<TickSource> makeSystemTickSource() {
+ class Steady : public TickSource {
+ using C = std::chrono::steady_clock; // NOLINT
+ Tick getTicksPerSecond() override {
+ static_assert(C::period::num == 1, "Fractional frequency disallowed");
+ return C::period::den;
+ }
+ Tick getTicks() override {
+ return C::now().time_since_epoch().count();
+ }
+ };
+ return std::make_unique<Steady>();
+}
+
+TickSource* globalSystemTickSource() {
+ static const auto p = makeSystemTickSource().release();
+ return p;
}
} // namespace mongo