| Index: base/time/time_win.cc
|
| diff --git a/base/time/time_win.cc b/base/time/time_win.cc
|
| index b81cadf39f67207d2c5e4988d7674c21bf10aafb..ff1e0169daf2f3853cf8b58de80634c0f6bb2882 100644
|
| --- a/base/time/time_win.cc
|
| +++ b/base/time/time_win.cc
|
| @@ -95,6 +95,15 @@ const int kMinTimerIntervalLowResMs = 4;
|
| bool g_high_res_timer_enabled = false;
|
| // How many times the high resolution timer has been called.
|
| uint32_t g_high_res_timer_count = 0;
|
| +// Start time of the high resolution timer usage monitoring. This is needed
|
| +// to calculate the usage as percentage of the total elapsed time.
|
| +TimeTicks g_high_res_timer_usage_start;
|
| +// The cumulative time the high resolution timer has been in use since
|
| +// |g_high_res_timer_usage_start| moment.
|
| +TimeDelta g_high_res_timer_usage;
|
| +// Timestamp of the last activation change of the high resolution timer. This
|
| +// is used to calculate the cumulative usage.
|
| +TimeTicks g_high_res_timer_last_activation;
|
| // The lock to control access to the above two variables.
|
| base::Lock* GetHighResLock() {
|
| static auto* lock = new base::Lock();
|
| @@ -218,13 +227,18 @@ bool Time::ActivateHighResolutionTimer(bool activating) {
|
| if (activating) {
|
| DCHECK_NE(g_high_res_timer_count, max);
|
| ++g_high_res_timer_count;
|
| - if (g_high_res_timer_count == 1)
|
| + if (g_high_res_timer_count == 1) {
|
| + g_high_res_timer_last_activation = TimeTicks::Now();
|
| timeBeginPeriod(period);
|
| + }
|
| } else {
|
| DCHECK_NE(g_high_res_timer_count, 0u);
|
| --g_high_res_timer_count;
|
| - if (g_high_res_timer_count == 0)
|
| + if (g_high_res_timer_count == 0) {
|
| + g_high_res_timer_usage +=
|
| + TimeTicks::Now() - g_high_res_timer_last_activation;
|
| timeEndPeriod(period);
|
| + }
|
| }
|
| return (period == kMinTimerIntervalHighResMs);
|
| }
|
| @@ -236,6 +250,35 @@ bool Time::IsHighResolutionTimerInUse() {
|
| }
|
|
|
| // static
|
| +void Time::ResetHighResolutionTimerUsage() {
|
| + base::AutoLock lock(*GetHighResLock());
|
| + g_high_res_timer_usage = TimeDelta();
|
| + g_high_res_timer_usage_start = TimeTicks::Now();
|
| + if (g_high_res_timer_count > 0)
|
| + g_high_res_timer_last_activation = g_high_res_timer_usage_start;
|
| +}
|
| +
|
| +// static
|
| +double Time::GetHighResolutionTimerUsage() {
|
| + base::AutoLock lock(*GetHighResLock());
|
| + TimeTicks now = TimeTicks::Now();
|
| + TimeDelta elapsed_time = now - g_high_res_timer_usage_start;
|
| + if (elapsed_time.is_zero()) {
|
| + // This is unexpected but possible if TimeTicks resolution is low and
|
| + // GetHighResolutionTimerUsage() is called promptly after
|
| + // ResetHighResolutionTimerUsage().
|
| + return 0.0;
|
| + }
|
| + TimeDelta used_time = g_high_res_timer_usage;
|
| + if (g_high_res_timer_count > 0) {
|
| + // If currently activated add the remainder of time since the last
|
| + // activation.
|
| + used_time += now - g_high_res_timer_last_activation;
|
| + }
|
| + return used_time.InMillisecondsF() / elapsed_time.InMillisecondsF() * 100;
|
| +}
|
| +
|
| +// static
|
| bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
|
| // Create the system struct representing our exploded time. It will either be
|
| // in local time or UTC.If casting from int to WORD results in overflow,
|
|
|