diff options
author | Tim Mayberry <mojofunk@gmail.com> | 2015-09-16 23:21:38 +1000 |
---|---|---|
committer | Tim Mayberry <mojofunk@gmail.com> | 2015-09-16 23:59:38 +1000 |
commit | 119e56e7eb9c58df0ac69e0e94dd6e008701b69c (patch) | |
tree | d3c08c99336a94660faed00367b1a3374e3039f5 /libs/pbd/windows_timer_utils.cc | |
parent | 9bd893a6a28912ed2905a6d01d7a7abea79e58eb (diff) |
Add PBD::QPC::initialize to initialize timer and call it from PBD::init
Check timer for invalid frequency
Precalculate timer tick rate to save a few instructions
Don't use static variables inside functions to avoid checking for initialization
Use static functions inside anonymous namespace for internal linkage
Diffstat (limited to 'libs/pbd/windows_timer_utils.cc')
-rw-r--r-- | libs/pbd/windows_timer_utils.cc | 63 |
1 files changed, 27 insertions, 36 deletions
diff --git a/libs/pbd/windows_timer_utils.cc b/libs/pbd/windows_timer_utils.cc index 2817b8e3a9..ab45e30d80 100644 --- a/libs/pbd/windows_timer_utils.cc +++ b/libs/pbd/windows_timer_utils.cc @@ -23,11 +23,15 @@ #include "pbd/compose.h" #include "pbd/debug.h" +#include "pbd/error.h" + +#include "i18n.h" #define DEBUG_TIMING(msg) DEBUG_TRACE (PBD::DEBUG::Timing, msg); namespace { +static UINT& timer_resolution () { @@ -35,7 +39,7 @@ timer_resolution () return timer_res_ms; } -} +} // namespace namespace PBD { @@ -100,6 +104,7 @@ reset_resolution () DEBUG_TIMING("Could not reset the Timer resolution.\n"); return false; } + DEBUG_TIMING("Reset the Timer resolution.\n"); timer_resolution() = 0; return true; } @@ -108,34 +113,9 @@ reset_resolution () namespace { -bool& -qpc_frequency_success () -{ - static bool success = false; - return success; -} - -LARGE_INTEGER -qpc_frequency () -{ - LARGE_INTEGER freq; - if (QueryPerformanceFrequency(&freq) == 0) { - DEBUG_TIMING ("Failed to determine frequency of QPC\n"); - qpc_frequency_success() = false; - } else { - qpc_frequency_success() = true; - } - - return freq; -} - -LARGE_INTEGER -qpc_frequency_cached () -{ - static LARGE_INTEGER frequency = qpc_frequency (); - return frequency; -} +static double timer_rate_us = 0.0; +static bool test_qpc_validity () { @@ -159,25 +139,37 @@ namespace QPC { bool check_timer_valid () { - // setup caching the timer frequency - qpc_frequency_cached (); - if (!qpc_frequency_success ()) { + if (!timer_rate_us) { return false; } return test_qpc_validity (); } +bool +initialize () +{ + LARGE_INTEGER freq; + if (!QueryPerformanceFrequency(&freq) || freq.QuadPart < 1) { + info << X_("Failed to determine frequency of QPC\n") << endmsg; + timer_rate_us = 0; + } else { + timer_rate_us = 1000000.0 / freq.QuadPart; + } + info << string_compose(X_("QPC timer microseconds per tick: %1\n"), + timer_rate_us) << endmsg; + return !timer_rate_us; +} + int64_t get_microseconds () { LARGE_INTEGER current_val; - if (qpc_frequency_success()) { + if (timer_rate_us) { // MS docs say this will always succeed for systems >= XP but it may // not return a monotonic value with non-invariant TSC's etc if (QueryPerformanceCounter(¤t_val) != 0) { - return (int64_t)(((double)current_val.QuadPart) / - ((double)qpc_frequency_cached().QuadPart) * 1000000.0); + return (int64_t)(current_val.QuadPart * timer_rate_us); } } DEBUG_TIMING ("Could not get QPC timer\n"); @@ -189,8 +181,7 @@ get_microseconds () int64_t get_microseconds () { - qpc_frequency_cached(); - if (qpc_frequency_success()) { + if (timer_rate_us) { return QPC::get_microseconds (); } // For XP systems that don't support a high-res performance counter |