Commit 4d40950e authored by Andrei-Laurențiu Olteanu's avatar Andrei-Laurențiu Olteanu Committed by Commit Bot

[Telemetry SWX] Convert user idle time to ms

idle_time_user_hz is measured in USER_HZ (clock ticks), a system
constant accessible via sysconf(_SC_CLK_TCK) (clock ticks / second).
Dividing the two results in the number of idle seconds and multiplying
by 1000 gets the result in milliseconds.

Add a wrapper around LogicalCpuInfoPtr::UncheckedConvertPtr to make
unittesting of the function easier without mocking the system call
sysconf().

Add tests for checking LogicalCpuInfoPtr::UncheckedConvertPtr.

Bug: b:161219494
Change-Id: I0c01f63100beea5315e1cc8f215eeb2fac6e76ff
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2301144Reviewed-by: default avatarOleh Lamzin <lamzin@google.com>
Reviewed-by: default avatarMahmoud Gawad <mgawad@google.com>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Commit-Queue: Laurențiu Olteanu <lolteanu@google.com>
Cr-Commit-Position: refs/heads/master@{#790293}
parent 19b7012e
...@@ -37,10 +37,11 @@ ...@@ -37,10 +37,11 @@
// 3.2) use string to store serial in a decimal numeral system instead // 3.2) use string to store serial in a decimal numeral system instead
// of uint32 in case we want to extend serial number range. // of uint32 in case we want to extend serial number range.
// 4) LogicalCpuInfo: // 4) LogicalCpuInfo:
// 4.1) rename idle_time_user_hz to idle_time_user, because of typo in // 4.1) rename idle_time_user_hz to idle_time_ms and use milliseconds
// cros_healthd interface; // instead of USER_HZ units, because USER_HZ system constant is not
// 4.2) use uint64 to store idle_time_user instead of uint32, // available in the web.
// idle_time_user can easily be more than uint32 range. // 4.2) use uint64 to store idle_time_ms instead of uint32, idle_time_ms
// can easily be more than uint32 range.
// 5) MemoryInfo: use uint64 to store page_faults_since_last_boot instead of // 5) MemoryInfo: use uint64 to store page_faults_since_last_boot instead of
// uint32, it can be more than uint32 range. // uint32, it can be more than uint32 range.
...@@ -252,9 +253,8 @@ struct LogicalCpuInfo { ...@@ -252,9 +253,8 @@ struct LogicalCpuInfo {
UInt32Value? scaling_max_frequency_khz; UInt32Value? scaling_max_frequency_khz;
// Current frequency the CPU is running at. // Current frequency the CPU is running at.
UInt32Value? scaling_current_frequency_khz; UInt32Value? scaling_current_frequency_khz;
// Idle time since last boot. USER_HZ can be converted to seconds // Idle time since last boot, in milliseconds.
// with the conversion factor given by sysconf(_SC_CLK_TCK). UInt64Value? idle_time_ms;
UInt64Value? idle_time_user;
// Information about the logical CPU's time in various C-states. // Information about the logical CPU's time in various C-states.
array<CpuCStateInfo> c_states; array<CpuCStateInfo> c_states;
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chromeos/components/telemetry_extension_ui/probe_service_converters.h" #include "chromeos/components/telemetry_extension_ui/probe_service_converters.h"
#include <unistd.h>
#include <utility> #include <utility>
#include "base/notreached.h" #include "base/notreached.h"
...@@ -138,13 +139,34 @@ health::mojom::CpuCStateInfoPtr UncheckedConvertPtr( ...@@ -138,13 +139,34 @@ health::mojom::CpuCStateInfoPtr UncheckedConvertPtr(
std::move(input->name), Convert(input->time_in_state_since_last_boot_us)); std::move(input->name), Convert(input->time_in_state_since_last_boot_us));
} }
namespace {
uint64_t UserHz() {
const long user_hz = sysconf(_SC_CLK_TCK);
DCHECK(user_hz >= 0);
return user_hz;
}
} // namespace
health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr(
cros_healthd::mojom::LogicalCpuInfoPtr input) { cros_healthd::mojom::LogicalCpuInfoPtr input) {
return UncheckedConvertPtr(std::move(input), UserHz());
}
health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr(
cros_healthd::mojom::LogicalCpuInfoPtr input,
uint64_t user_hz) {
constexpr uint64_t kMillisecondsInSecond = 1000;
uint64_t idle_time_user_hz = static_cast<uint64_t>(input->idle_time_user_hz);
DCHECK(user_hz != 0);
return health::mojom::LogicalCpuInfo::New( return health::mojom::LogicalCpuInfo::New(
Convert(input->max_clock_speed_khz), Convert(input->max_clock_speed_khz),
Convert(input->scaling_max_frequency_khz), Convert(input->scaling_max_frequency_khz),
Convert(input->scaling_current_frequency_khz), Convert(input->scaling_current_frequency_khz),
Convert(static_cast<uint64_t>(input->idle_time_user_hz)), Convert(idle_time_user_hz * kMillisecondsInSecond / user_hz),
ConvertPtrVector<health::mojom::CpuCStateInfoPtr>( ConvertPtrVector<health::mojom::CpuCStateInfoPtr>(
std::move(input->c_states))); std::move(input->c_states)));
} }
......
...@@ -58,6 +58,10 @@ health::mojom::CpuCStateInfoPtr UncheckedConvertPtr( ...@@ -58,6 +58,10 @@ health::mojom::CpuCStateInfoPtr UncheckedConvertPtr(
health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr( health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr(
cros_healthd::mojom::LogicalCpuInfoPtr input); cros_healthd::mojom::LogicalCpuInfoPtr input);
health::mojom::LogicalCpuInfoPtr UncheckedConvertPtr(
cros_healthd::mojom::LogicalCpuInfoPtr input,
uint64_t user_hz);
health::mojom::PhysicalCpuInfoPtr UncheckedConvertPtr( health::mojom::PhysicalCpuInfoPtr UncheckedConvertPtr(
cros_healthd::mojom::PhysicalCpuInfoPtr input); cros_healthd::mojom::PhysicalCpuInfoPtr input);
......
...@@ -285,7 +285,10 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) { ...@@ -285,7 +285,10 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) {
constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 10000; constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 10000;
constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 20000; constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 20000;
constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 30000; constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 30000;
constexpr uint32_t kIdleTimeUserHz = (1 << 28) + 40000;
// Idle time cannot be tested with ConvertPtr, because it requires USER_HZ
// system constant to convert idle_time_user_hz to milliseconds.
constexpr uint32_t kIdleTime = 0;
constexpr char kCpuCStateName[] = "C1"; constexpr char kCpuCStateName[] = "C1";
constexpr uint64_t kCpuCStateTime = (1 << 27) + 50000; constexpr uint64_t kCpuCStateTime = (1 << 27) + 50000;
...@@ -299,7 +302,7 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) { ...@@ -299,7 +302,7 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) {
input->max_clock_speed_khz = kMaxClockSpeedKhz; input->max_clock_speed_khz = kMaxClockSpeedKhz;
input->scaling_max_frequency_khz = kScalingMaxFrequencyKhz; input->scaling_max_frequency_khz = kScalingMaxFrequencyKhz;
input->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz; input->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz;
input->idle_time_user_hz = kIdleTimeUserHz; input->idle_time_user_hz = kIdleTime;
input->c_states.push_back(std::move(c_state)); input->c_states.push_back(std::move(c_state));
} }
...@@ -312,17 +315,33 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) { ...@@ -312,17 +315,33 @@ TEST(ProbeServiceConvertors, LogicalCpuInfoPtr) {
health::mojom::UInt32Value::New(kMaxClockSpeedKhz), health::mojom::UInt32Value::New(kMaxClockSpeedKhz),
health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz), health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz),
health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz), health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz),
health::mojom::UInt64Value::New(kIdleTimeUserHz), health::mojom::UInt64Value::New(kIdleTime),
std::move(expected_c_states))); std::move(expected_c_states)));
} }
TEST(ProbeServiceConvertors, LogicalCpuInfoPtrNonZeroIdleTime) {
constexpr uint64_t kUserHz = 100;
constexpr uint32_t kIdleTimeUserHz = 4291234295;
constexpr uint64_t kIdleTimeMs = 42912342950;
auto input = cros_healthd::mojom::LogicalCpuInfo::New();
input->idle_time_user_hz = kIdleTimeUserHz;
const auto output = unchecked::UncheckedConvertPtr(std::move(input), kUserHz);
ASSERT_TRUE(output);
EXPECT_EQ(output->idle_time_ms, health::mojom::UInt64Value::New(kIdleTimeMs));
}
TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) { TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) {
constexpr char kModelName[] = "i9"; constexpr char kModelName[] = "i9";
constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 11111; constexpr uint32_t kMaxClockSpeedKhz = (1 << 31) + 11111;
constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 22222; constexpr uint32_t kScalingMaxFrequencyKhz = (1 << 30) + 22222;
constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 33333; constexpr uint32_t kScalingCurrentFrequencyKhz = (1 << 29) + 33333;
constexpr uint32_t kIdleTimeUserHz = (1 << 28) + 44444;
// Idle time cannot be tested with ConvertPtr, because it requires USER_HZ
// system constant to convert idle_time_user_hz to milliseconds.
constexpr uint32_t kIdleTime = 0;
auto input = cros_healthd::mojom::PhysicalCpuInfo::New(); auto input = cros_healthd::mojom::PhysicalCpuInfo::New();
{ {
...@@ -330,7 +349,7 @@ TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) { ...@@ -330,7 +349,7 @@ TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) {
logical_info->max_clock_speed_khz = kMaxClockSpeedKhz; logical_info->max_clock_speed_khz = kMaxClockSpeedKhz;
logical_info->scaling_max_frequency_khz = kScalingMaxFrequencyKhz; logical_info->scaling_max_frequency_khz = kScalingMaxFrequencyKhz;
logical_info->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz; logical_info->scaling_current_frequency_khz = kScalingCurrentFrequencyKhz;
logical_info->idle_time_user_hz = kIdleTimeUserHz; logical_info->idle_time_user_hz = kIdleTime;
input->model_name = kModelName; input->model_name = kModelName;
input->logical_cpus.push_back(std::move(logical_info)); input->logical_cpus.push_back(std::move(logical_info));
...@@ -341,7 +360,7 @@ TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) { ...@@ -341,7 +360,7 @@ TEST(ProbeServiceConvertors, PhysicalCpuInfoPtr) {
health::mojom::UInt32Value::New(kMaxClockSpeedKhz), health::mojom::UInt32Value::New(kMaxClockSpeedKhz),
health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz), health::mojom::UInt32Value::New(kScalingMaxFrequencyKhz),
health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz), health::mojom::UInt32Value::New(kScalingCurrentFrequencyKhz),
health::mojom::UInt64Value::New(kIdleTimeUserHz), health::mojom::UInt64Value::New(kIdleTime),
std::vector<health::mojom::CpuCStateInfoPtr>{})); std::vector<health::mojom::CpuCStateInfoPtr>{}));
EXPECT_EQ(ConvertPtr(std::move(input)), EXPECT_EQ(ConvertPtr(std::move(input)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment