mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-07 07:14:56 +01:00
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
This commit is contained in:
parent
9bd893a6a2
commit
119e56e7eb
3 changed files with 41 additions and 40 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue