diff --git a/src/timers.cc b/src/timers.cc index d0821f31..7ba540b8 100644 --- a/src/timers.cc +++ b/src/timers.cc @@ -126,8 +126,12 @@ double ProcessCPUUsage() { return MakeTime(kernel_time, user_time); DiagnoseAndExit("GetProccessTimes() failed"); #elif defined(BENCHMARK_OS_QURT) + // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0, + // and doesn't appear to work on at least some devices (eg Samsung S22), + // so let's use the actually-documented and apparently-equivalent + // qurt_sysclock_get_hw_ticks() call instead. return static_cast( - qurt_timer_timetick_to_us(qurt_timer_get_ticks())) * + qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) * 1.0e-6; #elif defined(BENCHMARK_OS_EMSCRIPTEN) // clock_gettime(CLOCK_PROCESS_CPUTIME_ID, ...) returns 0 on Emscripten. @@ -160,8 +164,12 @@ double ThreadCPUUsage() { &user_time); return MakeTime(kernel_time, user_time); #elif defined(BENCHMARK_OS_QURT) + // Note that qurt_timer_get_ticks() is no longer documented as of SDK 5.3.0, + // and doesn't appear to work on at least some devices (eg Samsung S22), + // so let's use the actually-documented and apparently-equivalent + // qurt_sysclock_get_hw_ticks() call instead. return static_cast( - qurt_timer_timetick_to_us(qurt_timer_get_ticks())) * + qurt_timer_timetick_to_us(qurt_sysclock_get_hw_ticks())) * 1.0e-6; #elif defined(BENCHMARK_OS_MACOSX) // FIXME We want to use clock_gettime, but its not available in MacOS 10.11. diff --git a/src/timers.h b/src/timers.h index 65606ccd..690086b3 100644 --- a/src/timers.h +++ b/src/timers.h @@ -15,6 +15,29 @@ double ChildrenCPUUsage(); // Return the CPU usage of the current thread double ThreadCPUUsage(); +#if defined(BENCHMARK_OS_QURT) + +// std::chrono::now() can return 0 on some Hexagon devices; +// this reads the value of a 56-bit, 19.2MHz hardware counter +// and converts it to seconds. Unlike std::chrono, this doesn't +// return an absolute time, but since ChronoClockNow() is only used +// to compute elapsed time, this shouldn't matter. +struct QuRTClock { + typedef uint64_t rep; + typedef std::ratio<1, 19200000> period; + typedef std::chrono::duration duration; + typedef std::chrono::time_point time_point; + static const bool is_steady = false; + + static time_point now() { + unsigned long long count; + asm volatile(" %0 = c31:30 " : "=r"(count)); + return time_point(static_cast(count)); + } +}; + +#else + #if defined(HAVE_STEADY_CLOCK) template struct ChooseSteadyClock { @@ -25,10 +48,14 @@ template <> struct ChooseSteadyClock { typedef std::chrono::steady_clock type; }; +#endif // HAVE_STEADY_CLOCK + #endif struct ChooseClockType { -#if defined(HAVE_STEADY_CLOCK) +#if defined(BENCHMARK_OS_QURT) + typedef QuRTClock type; +#elif defined(HAVE_STEADY_CLOCK) typedef ChooseSteadyClock<>::type type; #else typedef std::chrono::high_resolution_clock type;