diff options
Diffstat (limited to 'o3d/statsreport/common')
-rw-r--r-- | o3d/statsreport/common/build.scons | 53 | ||||
-rw-r--r-- | o3d/statsreport/common/const_product.h | 91 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-linux.cc | 59 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-linux.h | 106 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-mac.cc | 70 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-mac.h | 103 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-win32.cc | 72 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer-win32.h | 105 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer.h | 40 | ||||
-rw-r--r-- | o3d/statsreport/common/highres_timer_unittest.cc | 84 |
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()); +} |