0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

SERVER-5557: Higher performance timer on Linux.

Also supports systems that implement POSIX's clock_gettime() (i.e., FreeBSD).
This commit is contained in:
Andy Schwerin 2012-04-20 17:45:13 -04:00
parent 5173201c78
commit 84614c30a3
11 changed files with 158 additions and 21 deletions

View File

@ -781,6 +781,12 @@ def doConfigure(myenv):
l + boostCompiler + boostVersion ], language='C++' ):
Exit(1)
if conf.CheckHeader('unistd.h'):
myenv.Append(CPPDEFINES=['MONGO_HAVE_HEADER_UNISTD_H'])
if solaris or conf.CheckDeclaration('clock_gettime', includes='#include <time.h>'):
conf.CheckLib('rt')
if (conf.CheckCXXHeader( "execinfo.h" ) and
conf.CheckDeclaration('backtrace', includes='#include <execinfo.h>') and
conf.CheckDeclaration('backtrace_symbols', includes='#include <execinfo.h>')):
@ -790,7 +796,6 @@ def doConfigure(myenv):
myenv["_HAVEPCAP"] = conf.CheckLib( ["pcap", "wpcap"], autoadd=False )
if solaris:
conf.CheckLib( "rt" )
conf.CheckLib( "nsl" )
if usev8:

View File

@ -51,6 +51,7 @@ clientSource = [
'mongo/util/signal_handlers.cpp',
'mongo/util/stringutils.cpp',
'mongo/util/text.cpp',
'mongo/util/timer.cpp',
'mongo/util/trace.cpp',
'mongo/util/util.cpp',
]

View File

@ -34,6 +34,7 @@ commonFiles = [ "pch.cpp",
"shell/mongo.cpp",
"util/background.cpp",
"util/intrusive_counter.cpp",
"util/timer.cpp",
"util/util.cpp",
"util/file_allocator.cpp",
"util/assert_util.cpp",

View File

@ -16,9 +16,12 @@
*/
#include "pch.h"
#include <fcntl.h>
#include <errno.h>
#include <boost/thread.hpp>
#if defined(__freebsd__) || defined(__openbsd__)
#include <sys/stat.h>
#endif
@ -27,8 +30,9 @@
#include <sys/vfs.h>
#endif
#include "timer.h"
#include "mongoutils/str.h"
#include "mongo/util/time_support.h"
#include "mongo/util/timer.h"
#include "mongo/util/mongoutils/str.h"
using namespace mongoutils;
#ifndef O_NOATIME

View File

@ -26,6 +26,8 @@
#pragma once
#define MONGO_TIMER_IMPL_GENERIC
#include "mongo/util/time_support.h"
namespace mongo {

View File

@ -25,8 +25,24 @@
#pragma once
#if defined(_WIN32)
#include "mongo/util/timer-win32-inl.h"
#else
#include "mongo/util/timer-generic-inl.h"
#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

View File

@ -0,0 +1,46 @@
/* Copyright 2010 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* 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 {
unsigned long long Timer::now() const {
timespec the_time;
unsigned 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<unsigned long long>(the_time.tv_sec);
result *= nanosPerSecond;
result += static_cast<unsigned long long>(the_time.tv_nsec);
return result;
}
} // namespace mongo

View File

@ -26,11 +26,15 @@
#pragma once
#define MONGO_TIMER_IMPL_WIN32
#include "mongo/util/assert_util.h"
namespace mongo {
unsigned long long Timer::now() const {
LARGE_INTEGER i;
QueryPerformanceCounter(&i);
fassert(16161, QueryPerformanceCounter(&i));
return i.QuadPart;
}

70
src/mongo/util/timer.cpp Normal file
View File

@ -0,0 +1,70 @@
// @file mongo/util/timer.cpp
/* Copyright 2009 10gen Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pch.h" // TODO: Replace with platform/base.h after it's checked in.
#include "mongo/util/timer.h"
#include <limits>
namespace mongo {
unsigned long long Timer::_countsPerSecond;
namespace {
// TODO: SERVER-5112, better startup-time initialization of C++ modules.
struct AtStartup {
AtStartup();
} atstartuputil;
#if defined(MONGO_TIMER_IMPL_WIN32)
AtStartup::AtStartup() {
LARGE_INTEGER x;
bool ok = QueryPerformanceFrequency(&x);
verify(ok);
Timer::_countsPerSecond = x.QuadPart;
}
#elif defined(MONGO_TIMER_IMPL_POSIX_MONOTONIC_CLOCK)
AtStartup::AtStartup() {
Timer::_countsPerSecond = Timer::nanosPerSecond;
// 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.
unsigned long long maxSecs = std::numeric_limits<unsigned long long>::max() /
Timer::nanosPerSecond;
timespec the_time;
fassert(16162, !clock_gettime(CLOCK_MONOTONIC, &the_time));
fassert(16163, static_cast<unsigned 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"
#endif
} // namespace
} // namespace mongo

View File

@ -34,6 +34,7 @@ namespace mongo {
public:
static const unsigned long long millisPerSecond = 1000;
static const unsigned long long microsPerSecond = 1000 * millisPerSecond;
static const unsigned long long nanosPerSecond = 1000 * microsPerSecond;
Timer() { reset(); }
int seconds() const { return (int)(micros() / 1000000); }

View File

@ -26,19 +26,6 @@
namespace mongo {
unsigned long long Timer::_countsPerSecond = Timer::microsPerSecond;
#if defined(_WIN32)
struct AtStartup {
AtStartup() {
LARGE_INTEGER x;
bool ok = QueryPerformanceFrequency(&x);
verify(ok);
Timer::_countsPerSecond = x.QuadPart;
}
} atstartuputil;
#endif
string hexdump(const char *data, unsigned len) {
verify( len < 1000000 );
const unsigned char *p = (const unsigned char *) data;