summaryrefslogtreecommitdiffstats
path: root/o3d/statsreport/common
diff options
context:
space:
mode:
Diffstat (limited to 'o3d/statsreport/common')
-rw-r--r--o3d/statsreport/common/build.scons53
-rw-r--r--o3d/statsreport/common/const_product.h91
-rw-r--r--o3d/statsreport/common/highres_timer-linux.cc59
-rw-r--r--o3d/statsreport/common/highres_timer-linux.h106
-rw-r--r--o3d/statsreport/common/highres_timer-mac.cc70
-rw-r--r--o3d/statsreport/common/highres_timer-mac.h103
-rw-r--r--o3d/statsreport/common/highres_timer-win32.cc72
-rw-r--r--o3d/statsreport/common/highres_timer-win32.h105
-rw-r--r--o3d/statsreport/common/highres_timer.h40
-rw-r--r--o3d/statsreport/common/highres_timer_unittest.cc84
10 files changed, 783 insertions, 0 deletions
diff --git a/o3d/statsreport/common/build.scons b/o3d/statsreport/common/build.scons
new file mode 100644
index 0000000..489e911
--- /dev/null
+++ b/o3d/statsreport/common/build.scons
@@ -0,0 +1,53 @@
+# Copyright 2009, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Import('env')
+
+env.Append(
+ LIBPATH=[
+ '$LIBS_DIR'
+ ],
+ LIBS = ['o3d_base']
+)
+
+INPUTS = []
+
+if env['TARGET_PLATFORM'] == 'WINDOWS':
+ INPUTS += [
+ 'highres_timer-win32.cc',
+ ]
+
+if env['TARGET_PLATFORM'] == 'MAC':
+ INPUTS += [
+ 'highres_timer-mac.cc',
+ ]
+
+# Build a library called 'o3dStatsreport_Common' from the input sources.
+env.ComponentLibrary('o3dStatsreport_Common', INPUTS)
diff --git a/o3d/statsreport/common/const_product.h b/o3d/statsreport/common/const_product.h
new file mode 100644
index 0000000..ef4f624
--- /dev/null
+++ b/o3d/statsreport/common/const_product.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+// Product-specific constants.
+//
+
+#ifndef O3D_STATSREPORT_COMMON_CONST_PRODUCT_H_
+#define O3D_STATSREPORT_COMMON_CONST_PRODUCT_H_
+
+#include <build/build_config.h>
+#include "base/basictypes.h"
+
+#define _QUOTEME(x) #x
+#define QUOTEME(x) _QUOTEME(x)
+
+#define _WIDEN(X) L ## X
+#define WIDEN(X) _WIDEN(X)
+
+#define PRODUCT_NAME_STRING "o3d"
+#define PRODUCT_VERSION_STRING QUOTEME(O3D_VERSION_NUMBER)
+
+#define PRODUCT_NAME_STRING_WIDE WIDEN(PRODUCT_NAME_STRING)
+
+// keep these two in sync
+#define REGISTRY_KEY_NAME_STRING "o3d"
+#define REGISTRY_KEY_STRING "Software\\Google\\O3D"
+
+#ifdef OS_WIN
+const char kMetricsLockName[] = PRODUCT_NAME_STRING "MetricsAggregationlock";
+#endif
+
+const char kProductName[] = PRODUCT_NAME_STRING;
+
+// TODO: Determine if #define below is needed.
+// This is a string value to be found under they key
+// at REGISTRY_KEY_STRING. This is written by our
+// installer
+// #define INSTALL_DIR_VALUE_NAME "InstallDir"
+
+const char kUserAgent[] = "O3D-";
+
+const int kStatsUploadIntervalSec = 24 * 60 * 60; // once per day
+const int kStatsAggregationIntervalMSec = 5 * 60 * 1000; // every 5 minutes
+
+// Taken from Google Update
+// TODO: CRITICAL: Link to actual Google Update docs so that we don't have
+// to keep this up to date. It will mess with our logs.
+const wchar_t* const kRegValueUserId = L"ui";
+const wchar_t* const kRelativeGoopdateRegPath = L"Software\\Google\\Update\\";
+
+const wchar_t* const kClientstateRegistryKey =
+ L"Software\\Google\\Update\\ClientState\\"
+ L"{70308795-045C-42DA-8F4E-D452381A7459}";
+const wchar_t* const kOptInRegistryKey = L"usagestats";
+
+#define INTERNET_MAX_PATH_LENGTH 2048
+#define INTERNET_MAX_SCHEME_LENGTH 32
+#define INTERNET_MAX_URL_LENGTH (INTERNET_MAX_SCHEME_LENGTH \
+ + sizeof("://") \
+ + INTERNET_MAX_PATH_LENGTH)
+
+#endif // O3D_STATSREPORT_COMMON_CONST_PRODUCT_H_
diff --git a/o3d/statsreport/common/highres_timer-linux.cc b/o3d/statsreport/common/highres_timer-linux.cc
new file mode 100644
index 0000000..d577fc3
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-linux.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "statsreport/common/highres_timer.h"
+
+const uint64 MICROS_IN_MILLI = 1000L;
+const uint64 MICROS_IN_HALF_MILLI = 500L;
+const uint64 MICROS_IN_HALF_SECOND = 500000L;
+
+uint64 HighresTimer::GetElapsedMs() const {
+ uint64 end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearest ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ return (static_cast<uint64>(end_time - start_ticks_) +
+ MICROS_IN_HALF_MILLI) /
+ MICROS_IN_MILLI;
+}
+
+uint64 HighresTimer::GetElapsedSec() const {
+ uint64 end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearest ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ return (static_cast<uint64>(end_time - start_ticks_) +
+ MICROS_IN_HALF_SECOND) /
+ MICROS_IN_SECOND;
+}
diff --git a/o3d/statsreport/common/highres_timer-linux.h b/o3d/statsreport/common/highres_timer-linux.h
new file mode 100644
index 0000000..7574a8f
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-linux.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_STATSREPORT_COMMON_HIGHRES_TIMER_LINUX_H_
+#define O3D_STATSREPORT_COMMON_HIGHRES_TIMER_LINUX_H_
+
+#include "base/basictypes.h"
+
+#include <sys/time.h>
+
+const uint64 MICROS_IN_SECOND = 1000000L;
+
+// A handy class for reliably measuring wall-clock time with decent resolution.
+//
+// We want to measure time with high resolution on Linux. What to do?
+//
+// RDTSC? Sure, but how do you convert it to wall clock time?
+// clock_gettime? It's not in all Linuxes.
+//
+// Let's just use gettimeofday; it's good to the microsecond.
+class HighresTimer {
+ public:
+ // Captures the current start time
+ HighresTimer();
+
+ // Captures the current tick, can be used to reset a timer for reuse.
+ void Start();
+
+ // Returns the elapsed ticks with full resolution
+ uint64 GetElapsedTicks() const;
+
+ // Returns the elapsed time in milliseconds, rounded to the nearest
+ // millisecond.
+ uint64 GetElapsedMs() const;
+
+ // Returns the elapsed time in seconds, rounded to the nearest second.
+ uint64 GetElapsedSec() const;
+
+ uint64 start_ticks() const { return start_ticks_; }
+
+ // Returns timer frequency from cache, should be less
+ // overhead than ::QueryPerformanceFrequency
+ static uint64 GetTimerFrequency();
+ // Returns current ticks
+ static uint64 GetCurrentTicks();
+
+ private:
+ // Captured start time
+ uint64 start_ticks_;
+};
+
+inline HighresTimer::HighresTimer() {
+ Start();
+}
+
+inline void HighresTimer::Start() {
+ start_ticks_ = GetCurrentTicks();
+}
+
+inline uint64 HighresTimer::GetTimerFrequency() {
+ // fixed; one "tick" is one microsecond
+
+ return MICROS_IN_SECOND;
+}
+
+inline uint64 HighresTimer::GetCurrentTicks() {
+ timeval tv;
+ (void)gettimeofday(&tv, 0);
+
+ return tv.tv_sec * MICROS_IN_SECOND + tv.tv_usec;
+}
+
+inline uint64 HighresTimer::GetElapsedTicks() const {
+ return start_ticks_ - GetCurrentTicks();
+}
+
+#endif // O3D_STATSREPORT_COMMON_HIGHRES_TIMER_LINUX_H_
diff --git a/o3d/statsreport/common/highres_timer-mac.cc b/o3d/statsreport/common/highres_timer-mac.cc
new file mode 100644
index 0000000..aa14525
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-mac.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "statsreport/common/highres_timer.h"
+
+bool HighresTimer::perf_ratio_collected_ = false;
+mach_timebase_info_data_t HighresTimer::perf_ratio_ = {0};
+
+const uint64 NANOS_IN_MILLI = 1000000L;
+const uint64 NANOS_IN_HALF_MILLI = 500000L;
+const uint64 NANOS_IN_SECOND = 1000000000L;
+const uint64 NANOS_IN_HALF_SECOND = 500000000L;
+
+uint64 HighresTimer::GetElapsedMs() const {
+ uint64 end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearest ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ (void)GetTimerFrequency();
+ return (static_cast<uint64>(end_time - start_ticks_) * perf_ratio_.numer +
+ NANOS_IN_HALF_MILLI * perf_ratio_.denom) /
+ (NANOS_IN_MILLI * perf_ratio_.denom);
+}
+
+uint64 HighresTimer::GetElapsedSec() const {
+ uint64 end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearest ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ (void)GetTimerFrequency();
+ return (static_cast<uint64>(end_time - start_ticks_) * perf_ratio_.numer +
+ NANOS_IN_HALF_SECOND * perf_ratio_.denom) /
+ (NANOS_IN_SECOND * perf_ratio_.denom);
+}
+
+void HighresTimer::CollectPerfRatio() {
+ mach_timebase_info(&perf_ratio_);
+ perf_ratio_collected_ = true;
+}
diff --git a/o3d/statsreport/common/highres_timer-mac.h b/o3d/statsreport/common/highres_timer-mac.h
new file mode 100644
index 0000000..af512ac
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-mac.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_STATSREPORT_COMMON_HIGHRES_TIMER_MAC_H_
+#define O3D_STATSREPORT_COMMON_HIGHRES_TIMER_MAC_H_
+
+#include "base/basictypes.h"
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+
+// A handy class for reliably measuring wall-clock time with decent resolution.
+class HighresTimer {
+ public:
+ // Captures the current start time
+ HighresTimer();
+
+ // Captures the current tick, can be used to reset a timer for reuse.
+ void Start();
+
+ // Returns the elapsed ticks with full resolution
+ uint64 GetElapsedTicks() const;
+
+ // Returns the elapsed time in milliseconds, rounded to the nearest
+ // millisecond.
+ uint64 GetElapsedMs() const;
+
+ // Returns the elapsed time in seconds, rounded to the nearest second.
+ uint64 GetElapsedSec() const;
+
+ uint64 start_ticks() const { return start_ticks_; }
+
+ // Returns timer frequency from cache, should be less
+ // overhead than ::QueryPerformanceFrequency
+ static uint64 GetTimerFrequency();
+ // Returns current ticks
+ static uint64 GetCurrentTicks();
+
+ private:
+ static void CollectPerfRatio();
+
+ // Captured start time
+ uint64 start_ticks_;
+
+ // Captured performance counter frequency
+ static bool perf_ratio_collected_;
+ static mach_timebase_info_data_t perf_ratio_;
+};
+
+inline HighresTimer::HighresTimer() {
+ Start();
+}
+
+inline void HighresTimer::Start() {
+ start_ticks_ = GetCurrentTicks();
+}
+
+inline uint64 HighresTimer::GetTimerFrequency() {
+ if (!perf_ratio_collected_)
+ CollectPerfRatio();
+ // we're losing precision by doing the division here, but this value is only
+ // used to estimate tick time by the unit tests, so we're ok
+ return static_cast<uint64>(perf_ratio_.denom) * 1000000000ULL
+ / perf_ratio_.numer;
+}
+
+inline uint64 HighresTimer::GetCurrentTicks() {
+ return mach_absolute_time();
+}
+
+inline uint64 HighresTimer::GetElapsedTicks() const {
+ return start_ticks_ - GetCurrentTicks();
+}
+
+#endif // O3D_STATSREPORT_COMMON_HIGHRES_TIMER_MAC_H_
diff --git a/o3d/statsreport/common/highres_timer-win32.cc b/o3d/statsreport/common/highres_timer-win32.cc
new file mode 100644
index 0000000..878b237
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-win32.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "statsreport/common/highres_timer.h"
+
+bool HighresTimer::perf_freq_collected_ = false;
+ULONGLONG HighresTimer::perf_freq_ = 0;
+
+ULONGLONG HighresTimer::GetElapsedMs() const {
+ ULONGLONG end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearerst ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ // Given infinite resolution, this expression could be written as:
+ // trunc((end - start (units:freq*sec))/freq (units:sec) *
+ // 1000 (unit:ms) + 1/2 (unit:ms))
+ ULONGLONG freq = GetTimerFrequency();
+ return ((end_time - start_ticks_) * 1000L + freq / 2) / freq;
+}
+
+ULONGLONG HighresTimer::GetElapsedSec() const {
+ ULONGLONG end_time = GetCurrentTicks();
+
+ // Scale to ms and round to nearerst ms - rounding is important
+ // because otherwise the truncation error may accumulate e.g. in sums.
+ //
+ // Given infinite resolution, this expression could be written as:
+ // trunc((end - start (units:freq*sec))/freq (unit:sec) + 1/2 (unit:sec))
+ ULONGLONG freq = GetTimerFrequency();
+ return ((end_time - start_ticks_) + freq / 2) / freq;
+}
+
+void HighresTimer::CollectPerfFreq() {
+ LARGE_INTEGER freq;
+
+ // Note that this is racy. It's OK, however, because even
+ // concurrent executions of this are idempotent.
+ if (::QueryPerformanceFrequency(&freq)) {
+ perf_freq_ = freq.QuadPart;
+ perf_freq_collected_ = true;
+ }
+}
diff --git a/o3d/statsreport/common/highres_timer-win32.h b/o3d/statsreport/common/highres_timer-win32.h
new file mode 100644
index 0000000..378fdeb
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer-win32.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef O3D_STATSREPORT_COMMON_HIGHRES_TIMER_WIN32_H_
+#define O3D_STATSREPORT_COMMON_HIGHRES_TIMER_WIN32_H_
+
+#include <windows.h>
+
+// A handy class for reliably measuring wall-clock time with decent resolution,
+// even on multi-processor machines and on laptops (where RDTSC potentially
+// returns different results on different processors and/or the RDTSC timer
+// clocks at different rates depending on the power state of the CPU,
+// respectively).
+class HighresTimer {
+ public:
+ // Captures the current start time
+ HighresTimer();
+ virtual ~HighresTimer() {}
+
+ // Captures the current tick, can be used to reset a timer for reuse.
+ void Start();
+
+ // Returns the elapsed ticks with full resolution
+ ULONGLONG GetElapsedTicks() const;
+
+ // Returns the elapsed time in milliseconds, rounded to the nearest
+ // millisecond.
+ virtual ULONGLONG GetElapsedMs() const;
+
+ // Returns the elapsed time in seconds, rounded to the nearest second.
+ virtual ULONGLONG GetElapsedSec() const;
+
+ ULONGLONG start_ticks() const { return start_ticks_; }
+
+ // Returns timer frequency from cache, should be less
+ // overhead than ::QueryPerformanceFrequency
+ static ULONGLONG GetTimerFrequency();
+ // Returns current ticks
+ static ULONGLONG GetCurrentTicks();
+
+ private:
+ static void CollectPerfFreq();
+
+ // Captured start time
+ ULONGLONG start_ticks_;
+
+ // Captured performance counter frequency
+ static bool perf_freq_collected_;
+ static ULONGLONG perf_freq_;
+};
+
+inline HighresTimer::HighresTimer() {
+ Start();
+}
+
+inline void HighresTimer::Start() {
+ start_ticks_ = GetCurrentTicks();
+}
+
+inline ULONGLONG HighresTimer::GetTimerFrequency() {
+ if (!perf_freq_collected_)
+ CollectPerfFreq();
+ return perf_freq_;
+}
+
+inline ULONGLONG HighresTimer::GetCurrentTicks() {
+ LARGE_INTEGER ticks;
+ ::QueryPerformanceCounter(&ticks);
+ return ticks.QuadPart;
+}
+
+inline ULONGLONG HighresTimer::GetElapsedTicks() const {
+ return start_ticks_ - GetCurrentTicks();
+}
+
+#endif // O3D_STATSREPORT_COMMON_HIGHRES_TIMER_WIN32_H_
diff --git a/o3d/statsreport/common/highres_timer.h b/o3d/statsreport/common/highres_timer.h
new file mode 100644
index 0000000..5842729
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <build/build_config.h>
+#if defined(OS_WIN)
+#include "statsreport/common/highres_timer-win32.h"
+#elif defined(OS_MACOSX)
+#include "statsreport/common/highres_timer-mac.h"
+#else
+#include "statsreport/common/highres_timer-linux.h"
+#endif
diff --git a/o3d/statsreport/common/highres_timer_unittest.cc b/o3d/statsreport/common/highres_timer_unittest.cc
new file mode 100644
index 0000000..7f40f10
--- /dev/null
+++ b/o3d/statsreport/common/highres_timer_unittest.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "statsreport/common/highres_timer.h"
+#include "gtest/gtest.h"
+#include "base/basictypes.h"
+
+// These unittests have proven to be flaky on the build server. While
+// we don't want them breaking the build, we still build them to guard
+// against bitrot. On dev's machines during local builds we leave them
+// enabled.
+#ifndef BUILD_SERVER_BUILD
+TEST(HighresTimer, MillisecondClock) {
+#else
+TEST(HighresTimer, DISABLED_MillisecondClock) {
+#endif
+ HighresTimer timer;
+
+ // note: this could fail if we context switch between initializing the timer
+ // and here. Very unlikely however.
+ EXPECT_EQ(0, timer.GetElapsedMs());
+ timer.Start();
+ uint64 half_ms = HighresTimer::GetTimerFrequency() / 2000;
+ // busy wait for half a millisecond
+ while (timer.start_ticks() + half_ms > HighresTimer::GetCurrentTicks()) {
+ // Nothing
+ }
+ EXPECT_EQ(1, timer.GetElapsedMs());
+}
+
+#ifndef BUILD_SERVER_BUILD
+TEST(HighresTimer, SecondClock) {
+#else
+TEST(HighresTimer, DISABLED_SecondClock) {
+#endif
+ HighresTimer timer;
+
+ EXPECT_EQ(0, timer.GetElapsedSec());
+#ifdef OS_WIN
+ ::Sleep(250);
+#else
+ struct timespec ts1 = {0, 250000000};
+ nanosleep(&ts1, 0);
+#endif
+ EXPECT_EQ(0, timer.GetElapsedSec());
+ EXPECT_LE(230, timer.GetElapsedMs());
+ EXPECT_GE(270, timer.GetElapsedMs());
+#ifdef OS_WIN
+ ::Sleep(251);
+#else
+ struct timespec ts2 = {0, 251000000};
+ nanosleep(&ts2, 0);
+#endif
+ EXPECT_EQ(1, timer.GetElapsedSec());
+}