0

[power_sampler] Add resource coalition sampler.

The resource coalition sampler produces resource usage stats for a
group of processes.

Bug: 1254332
Change-Id: I79dd6013fc7a46c81c01f407a0b2546cad2440bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3298313
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Cr-Commit-Position: refs/heads/main@{#945470}
This commit is contained in:
Francois Doray
2021-11-25 20:36:01 +00:00
committed by Chromium LUCI CQ
parent 4357c2ffb0
commit 7fd6b3bce5
10 changed files with 1003 additions and 7 deletions

@ -20,7 +20,10 @@ if (is_mac) {
source_set("unit_tests") {
testonly = true
sources = [ "energy_impact_mac_unittest.mm" ]
sources = [
"energy_impact_mac_unittest.mm",
"resource_coalition_mac_unittest.mm",
]
data = [ "test/data/" ]

@ -29,6 +29,12 @@ absl::optional<uint64_t> GetProcessCoalitionId(base::ProcessId pid);
std::unique_ptr<coalition_resource_usage> GetCoalitionResourceUsage(
int64_t coalition_id);
// Returns a `coalition_resource_usage` in which each member is the result of
// substracting the corresponding fields in `left` and `right`.
coalition_resource_usage GetCoalitionResourceUsageDifference(
const coalition_resource_usage& left,
const coalition_resource_usage& right);
} // namespace power_metrics
#endif // COMPONENTS_PPOWER_METRICS_RESOURCE_COALITION_MAC_H_

@ -36,4 +36,101 @@ std::unique_ptr<coalition_resource_usage> GetCoalitionResourceUsage(
return nullptr;
}
coalition_resource_usage GetCoalitionResourceUsageDifference(
const coalition_resource_usage& left,
const coalition_resource_usage& right) {
DCHECK_GE(left.tasks_started, right.tasks_started);
DCHECK_GE(left.tasks_exited, right.tasks_exited);
DCHECK_GE(left.time_nonempty, right.time_nonempty);
DCHECK_GE(left.cpu_time, right.cpu_time);
DCHECK_GE(left.interrupt_wakeups, right.interrupt_wakeups);
DCHECK_GE(left.platform_idle_wakeups, right.platform_idle_wakeups);
DCHECK_GE(left.bytesread, right.bytesread);
DCHECK_GE(left.byteswritten, right.byteswritten);
DCHECK_GE(left.gpu_time, right.gpu_time);
DCHECK_GE(left.cpu_time_billed_to_me, right.cpu_time_billed_to_me);
DCHECK_GE(left.cpu_time_billed_to_others, right.cpu_time_billed_to_others);
DCHECK_GE(left.energy, right.energy);
DCHECK_GE(left.logical_immediate_writes, right.logical_immediate_writes);
DCHECK_GE(left.logical_deferred_writes, right.logical_deferred_writes);
DCHECK_GE(left.logical_invalidated_writes, right.logical_invalidated_writes);
DCHECK_GE(left.logical_metadata_writes, right.logical_metadata_writes);
DCHECK_GE(left.logical_immediate_writes_to_external,
right.logical_immediate_writes_to_external);
DCHECK_GE(left.logical_deferred_writes_to_external,
right.logical_deferred_writes_to_external);
DCHECK_GE(left.logical_invalidated_writes_to_external,
right.logical_invalidated_writes_to_external);
DCHECK_GE(left.logical_metadata_writes_to_external,
right.logical_metadata_writes_to_external);
DCHECK_GE(left.energy_billed_to_me, right.energy_billed_to_me);
DCHECK_GE(left.energy_billed_to_others, right.energy_billed_to_others);
DCHECK_GE(left.cpu_ptime, right.cpu_ptime);
DCHECK_GE(left.cpu_instructions, right.cpu_instructions);
DCHECK_GE(left.cpu_cycles, right.cpu_cycles);
DCHECK_GE(left.fs_metadata_writes, right.fs_metadata_writes);
DCHECK_GE(left.pm_writes, right.pm_writes);
coalition_resource_usage ret;
ret.tasks_started = left.tasks_started - right.tasks_started;
ret.tasks_exited = left.tasks_exited - right.tasks_exited;
ret.time_nonempty = left.time_nonempty - right.time_nonempty;
ret.cpu_time = left.cpu_time - right.cpu_time;
ret.interrupt_wakeups = left.interrupt_wakeups - right.interrupt_wakeups;
ret.platform_idle_wakeups =
left.platform_idle_wakeups - right.platform_idle_wakeups;
ret.bytesread = left.bytesread - right.bytesread;
ret.byteswritten = left.byteswritten - right.byteswritten;
ret.gpu_time = left.gpu_time - right.gpu_time;
ret.cpu_time_billed_to_me =
left.cpu_time_billed_to_me - right.cpu_time_billed_to_me;
ret.cpu_time_billed_to_others =
left.cpu_time_billed_to_others - right.cpu_time_billed_to_others;
ret.energy = left.energy - right.energy;
ret.logical_immediate_writes =
left.logical_immediate_writes - right.logical_immediate_writes;
ret.logical_deferred_writes =
left.logical_deferred_writes - right.logical_deferred_writes;
ret.logical_invalidated_writes =
left.logical_invalidated_writes - right.logical_invalidated_writes;
ret.logical_metadata_writes =
left.logical_metadata_writes - right.logical_metadata_writes;
ret.logical_immediate_writes_to_external =
left.logical_immediate_writes_to_external -
right.logical_immediate_writes_to_external;
ret.logical_deferred_writes_to_external =
left.logical_deferred_writes_to_external -
right.logical_deferred_writes_to_external;
ret.logical_invalidated_writes_to_external =
left.logical_invalidated_writes_to_external -
right.logical_invalidated_writes_to_external;
ret.logical_metadata_writes_to_external =
left.logical_metadata_writes_to_external -
right.logical_metadata_writes_to_external;
ret.energy_billed_to_me =
left.energy_billed_to_me - right.energy_billed_to_me;
ret.energy_billed_to_others =
left.energy_billed_to_others - right.energy_billed_to_others;
ret.cpu_ptime = left.cpu_ptime - right.cpu_ptime;
DCHECK_EQ(left.cpu_time_eqos_len,
static_cast<uint64_t>(COALITION_NUM_THREAD_QOS_TYPES));
DCHECK_EQ(right.cpu_time_eqos_len,
static_cast<uint64_t>(COALITION_NUM_THREAD_QOS_TYPES));
ret.cpu_time_eqos_len = left.cpu_time_eqos_len;
for (int i = 0; i < COALITION_NUM_THREAD_QOS_TYPES; ++i) {
DCHECK_GE(left.cpu_time_eqos[i], right.cpu_time_eqos[i]);
ret.cpu_time_eqos[i] = left.cpu_time_eqos[i] - right.cpu_time_eqos[i];
}
ret.cpu_instructions = left.cpu_instructions - right.cpu_instructions;
ret.cpu_cycles = left.cpu_cycles - right.cpu_cycles;
ret.fs_metadata_writes = left.fs_metadata_writes - right.fs_metadata_writes;
ret.pm_writes = left.pm_writes - right.pm_writes;
return ret;
}
} // power_metrics

@ -0,0 +1,101 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/power_metrics/resource_coalition_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace power_metrics {
namespace {
coalition_resource_usage GetTestCoalitionResourceUsage(uint32_t increment) {
coalition_resource_usage ret{
.tasks_started = 1 + increment,
.tasks_exited = 2 + increment,
.time_nonempty = 3 + increment,
.cpu_time = 4 + increment,
.interrupt_wakeups = 5 + increment,
.platform_idle_wakeups = 6 + increment,
.bytesread = 7 + increment,
.byteswritten = 8 + increment,
.gpu_time = 9 + increment,
.cpu_time_billed_to_me = 10 + increment,
.cpu_time_billed_to_others = 11 + increment,
.energy = 12 + increment,
.logical_immediate_writes = 13 + increment,
.logical_deferred_writes = 14 + increment,
.logical_invalidated_writes = 15 + increment,
.logical_metadata_writes = 16 + increment,
.logical_immediate_writes_to_external = 17 + increment,
.logical_deferred_writes_to_external = 18 + increment,
.logical_invalidated_writes_to_external = 19 + increment,
.logical_metadata_writes_to_external = 20 + increment,
.energy_billed_to_me = 21 + increment,
.energy_billed_to_others = 22 + increment,
.cpu_ptime = 23 + increment,
.cpu_time_eqos_len = COALITION_NUM_THREAD_QOS_TYPES,
.cpu_instructions = 31 + increment,
.cpu_cycles = 32 + increment,
.fs_metadata_writes = 33 + increment,
.pm_writes = 34 + increment,
};
ret.cpu_time_eqos[THREAD_QOS_DEFAULT] = 24 + increment;
ret.cpu_time_eqos[THREAD_QOS_MAINTENANCE] = 25 + increment;
ret.cpu_time_eqos[THREAD_QOS_BACKGROUND] = 26 + increment;
ret.cpu_time_eqos[THREAD_QOS_UTILITY] = 27 + increment;
ret.cpu_time_eqos[THREAD_QOS_LEGACY] = 28 + increment;
ret.cpu_time_eqos[THREAD_QOS_USER_INITIATED] = 29 + increment;
ret.cpu_time_eqos[THREAD_QOS_USER_INTERACTIVE] = 30 + increment;
return ret;
}
} // namespace
TEST(ResourceCoalitionMacTest, Difference) {
coalition_resource_usage left =
GetTestCoalitionResourceUsage(/* increment= */ 1);
coalition_resource_usage right =
GetTestCoalitionResourceUsage(/* increment= */ 0);
coalition_resource_usage diff =
GetCoalitionResourceUsageDifference(left, right);
EXPECT_EQ(diff.tasks_started, 1U);
EXPECT_EQ(diff.tasks_exited, 1U);
EXPECT_EQ(diff.time_nonempty, 1U);
EXPECT_EQ(diff.cpu_time, 1U);
EXPECT_EQ(diff.interrupt_wakeups, 1U);
EXPECT_EQ(diff.platform_idle_wakeups, 1U);
EXPECT_EQ(diff.bytesread, 1U);
EXPECT_EQ(diff.byteswritten, 1U);
EXPECT_EQ(diff.gpu_time, 1U);
EXPECT_EQ(diff.cpu_time_billed_to_me, 1U);
EXPECT_EQ(diff.cpu_time_billed_to_others, 1U);
EXPECT_EQ(diff.energy, 1U);
EXPECT_EQ(diff.logical_immediate_writes, 1U);
EXPECT_EQ(diff.logical_deferred_writes, 1U);
EXPECT_EQ(diff.logical_invalidated_writes, 1U);
EXPECT_EQ(diff.logical_metadata_writes, 1U);
EXPECT_EQ(diff.logical_immediate_writes_to_external, 1U);
EXPECT_EQ(diff.logical_deferred_writes_to_external, 1U);
EXPECT_EQ(diff.logical_invalidated_writes_to_external, 1U);
EXPECT_EQ(diff.logical_metadata_writes_to_external, 1U);
EXPECT_EQ(diff.energy_billed_to_me, 1U);
EXPECT_EQ(diff.energy_billed_to_others, 1U);
EXPECT_EQ(diff.cpu_ptime, 1U);
EXPECT_EQ(diff.cpu_time_eqos_len,
static_cast<uint64_t>(COALITION_NUM_THREAD_QOS_TYPES));
for (int i = 0; i < COALITION_NUM_THREAD_QOS_TYPES; ++i)
EXPECT_EQ(diff.cpu_time_eqos[i], 1U);
EXPECT_EQ(diff.cpu_instructions, 1U);
EXPECT_EQ(diff.cpu_cycles, 1U);
EXPECT_EQ(diff.fs_metadata_writes, 1U);
EXPECT_EQ(diff.pm_writes, 1U);
}
} // namespace power_metrics