summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2014-06-03 16:52:03 -0400
committerBenety Goh <benety@mongodb.com>2014-06-05 23:03:50 -0400
commitffaa85ae89335efbef26338a12cc41b351fc8bda (patch)
treeb59b9b5f116ecf25f05f5855e749ec66363b4fc9 /src/mongo/util
parentc4fa4dc85aec3b8dfd9ada7a58521d8f1bbf4fff (diff)
downloadmongo-ffaa85ae89335efbef26338a12cc41b351fc8bda.tar.gz
SERVER-13792 added runtime and build-time checks for POSIX monotonic clocks. de-inlined Timer::now() implementations
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/timer-generic-inl.h49
-rw-r--r--src/mongo/util/timer-inl.h60
-rw-r--r--src/mongo/util/timer-posixclock-inl.h58
-rw-r--r--src/mongo/util/timer-win32-inl.h54
-rw-r--r--src/mongo/util/timer.cpp79
-rw-r--r--src/mongo/util/timer.h4
6 files changed, 68 insertions, 236 deletions
diff --git a/src/mongo/util/timer-generic-inl.h b/src/mongo/util/timer-generic-inl.h
deleted file mode 100644
index c0b07c563d7..00000000000
--- a/src/mongo/util/timer-generic-inl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// @file mongo/util/timer-generic-inl.h
-
-/* Copyright 2010 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-/**
- * Inline function implementations for the "generic" implementation of the
- * Timer class. This implementation often has pretty poor resolution, but is available
- * on all supported platforms.
- *
- * This file should only be included through timer-inl.h, which selects the
- * particular implementation based on target platform.
- */
-
-#pragma once
-
-#define MONGO_TIMER_IMPL_GENERIC
-
-#include "mongo/util/time_support.h"
-
-namespace mongo {
-
- long long Timer::now() const { return curTimeMicros64(); }
-
-} // namespace mongo
diff --git a/src/mongo/util/timer-inl.h b/src/mongo/util/timer-inl.h
deleted file mode 100644
index d4e037e2e96..00000000000
--- a/src/mongo/util/timer-inl.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// @file mongo/util/timer-inl.h
-
-/* Copyright 2010 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-/**
- * Inline function implementations for the Timer class. This file simply selects
- * the platform-appropriate inline functions to include.
- *
- * This file should only be included through timer-inl.h, which selects the
- * particular implementation based on target platform.
- */
-
-#pragma once
-
-#if defined(MONGO_HAVE_HEADER_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#if defined(_WIN32)
-
-// On Windows, prefer the Windows-specific implementation, which employs QueryPerformanceCounter.
-#include "mongo/util/timer-win32-inl.h"
-
-#elif defined(_POSIX_TIMERS) and _POSIX_TIMERS > 0 and defined(_POSIX_MONOTONIC_CLOCK) and _POSIX_MONOTONIC_CLOCK > 0
-
-// On systems that support the POSIX clock_gettime function, and the "monotonic" clock,
-// use those.
-#include "mongo/util/timer-posixclock-inl.h"
-
-#else
-
-// If all else fails, fall back to a generic implementation. Performance may suffer.
-#include "mongo/util/timer-generic-inl.h"
-
-#endif
diff --git a/src/mongo/util/timer-posixclock-inl.h b/src/mongo/util/timer-posixclock-inl.h
deleted file mode 100644
index a171c25ab0d..00000000000
--- a/src/mongo/util/timer-posixclock-inl.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2010 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-/**
- * Inline function implementations for timers on systems that support the
- * POSIX clock API and CLOCK_MONOTONIC clock.
- *
- * This file should only be included through timer-inl.h, which selects the
- * particular implementation based on target platform.
- */
-
-#define MONGO_TIMER_IMPL_POSIX_MONOTONIC_CLOCK
-
-#include <ctime>
-
-#include "mongo/util/assert_util.h"
-
-namespace mongo {
-
- long long Timer::now() const {
- 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 *= nanosPerSecond;
- result += static_cast<long long>(the_time.tv_nsec);
- return result;
- }
-
-} // namespace mongo
diff --git a/src/mongo/util/timer-win32-inl.h b/src/mongo/util/timer-win32-inl.h
deleted file mode 100644
index dedf77ca385..00000000000
--- a/src/mongo/util/timer-win32-inl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// @file mongo/util/timer-win32-inl.h
-
-/* Copyright 2010 10gen Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects
- * for all of the code used other than as permitted herein. If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so. If you do not
- * wish to do so, delete this exception statement from your version. If you
- * delete this exception statement from all source files in the program,
- * then also delete it in the license file.
- */
-
-/**
- * Inline function implementations for the 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.
- *
- * Do not include directly. Include "mongo/util/timer.h".
- */
-
-#pragma once
-
-#define MONGO_TIMER_IMPL_WIN32
-
-#include "mongo/platform/windows_basic.h"
-#include "mongo/util/assert_util.h"
-
-namespace mongo {
-
- long long Timer::now() const {
- LARGE_INTEGER i;
- fassert(16161, QueryPerformanceCounter(&i));
- return i.QuadPart;
- }
-
-} // namespace mongo
diff --git a/src/mongo/util/timer.cpp b/src/mongo/util/timer.cpp
index 597c4e15aa5..90e61b55423 100644
--- a/src/mongo/util/timer.cpp
+++ b/src/mongo/util/timer.cpp
@@ -27,14 +27,25 @@
* then also delete it in the license file.
*/
+#include "mongo/platform/basic.h"
+
#include "mongo/util/timer.h"
+#include <ctime>
#include <limits>
+#if defined(MONGO_HAVE_HEADER_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#include "mongo/util/assert_util.h"
+#include "mongo/util/time_support.h"
namespace mongo {
- // default value of 1 so that during startup initialization if referenced no division by zero
- long long Timer::_countsPerSecond = 1;
+ // Set default value to reflect "generic" timer implementation.
+ // Define Timer::_countsPerSecond before static initializer "atstartuputil" to ensure correct
+ // relative sequencing regardless of how _countsPerSecond is initialized (static or dynamic).
+ long long Timer::_countsPerSecond = Timer::microsPerSecond;
namespace {
@@ -43,19 +54,66 @@ namespace mongo {
AtStartup();
} atstartuputil;
-#if defined(MONGO_TIMER_IMPL_WIN32)
+ // "Generic" implementation for Timer::now().
+ long long _timerNowGeneric() {
+ return curTimeMicros64();
+ }
+
+ // Function pointer to Timer::now() implementation.
+ // Overridden in AtStartup() with better implementation where available.
+ long long (*_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.
+ */
+ long long timerNowWindows() {
+ LARGE_INTEGER i;
+ fassert(16161, QueryPerformanceCounter(&i));
+ return i.QuadPart;
+ }
AtStartup::AtStartup() {
LARGE_INTEGER x;
bool ok = QueryPerformanceFrequency(&x);
verify(ok);
Timer::_countsPerSecond = x.QuadPart;
+ _timerNow = &timerNowWindows;
}
-#elif defined(MONGO_TIMER_IMPL_POSIX_MONOTONIC_CLOCK)
+#elif defined(MONGO_HAVE_POSIX_MONOTONIC_CLOCK)
+
+ /**
+ * Implementation for timer on systems that support the
+ * POSIX clock API and CLOCK_MONOTONIC clock.
+ */
+ long long 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 *= Timer::nanosPerSecond;
+ result += static_cast<long long>(the_time.tv_nsec);
+ return result;
+ }
AtStartup::AtStartup() {
+ // If the monotonic clock is not available at runtime (sysconf() returns 0 or -1),
+ // do not override the generic implementation or modify Timer::_countsPerSecond.
+ if (sysconf(_SC_MONOTONIC_CLOCK) <= 0) {
+ return;
+ }
+
Timer::_countsPerSecond = Timer::nanosPerSecond;
+ _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.
@@ -65,17 +123,14 @@ namespace mongo {
fassert(16162, !clock_gettime(CLOCK_MONOTONIC, &the_time));
fassert(16163, static_cast<long long>(the_time.tv_sec) < maxSecs);
}
-
-#elif defined(MONGO_TIMER_IMPL_GENERIC)
-
- AtStartup::AtStartup() {
- Timer::_countsPerSecond = Timer::microsPerSecond;
- }
-
#else
-#error "Unknown mongo::Timer implementation"
+ AtStartup::AtStartup() { }
#endif
} // namespace
+ long long Timer::now() const {
+ return _timerNow();
+ }
+
} // namespace mongo
diff --git a/src/mongo/util/timer.h b/src/mongo/util/timer.h
index 0d5a5e97ebc..b28db52d703 100644
--- a/src/mongo/util/timer.h
+++ b/src/mongo/util/timer.h
@@ -85,10 +85,8 @@ namespace mongo {
static long long _countsPerSecond;
private:
- inline long long now() const;
+ long long now() const;
long long _old;
};
} // namespace mongo
-
-#include "mongo/util/timer-inl.h"