Merge "TraceWriterImpl: Fix a DCHECK in drop_packets_ mode."
diff --git a/docs/concepts/clock-sync.md b/docs/concepts/clock-sync.md
index 95a200f..4afb1b7 100644
--- a/docs/concepts/clock-sync.md
+++ b/docs/concepts/clock-sync.md
@@ -120,7 +120,7 @@
* Chose a fully qualified name for the clock domain
(e.g. `com.example.my_subsystem`)
-* Chose the clock ID as `(HASH("com.example.my_subsystem") + 128) & 0xFFFFFFF`
+* Chose the clock ID as `HASH("com.example.my_subsystem") | 0x80000000`
where `HASH(x)` is the FNV-1a hash of the fully qualified clock domain name.
### {#clock_snapshot} The ClockSnapshot trace packet
diff --git a/include/perfetto/ext/base/thread_utils.h b/include/perfetto/ext/base/thread_utils.h
index fb47d3d..2e9c4e5 100644
--- a/include/perfetto/ext/base/thread_utils.h
+++ b/include/perfetto/ext/base/thread_utils.h
@@ -70,7 +70,9 @@
}
#else
-inline void MaybeSetThreadName(const std::string&) {}
+inline bool MaybeSetThreadName(const std::string&) {
+ return false;
+}
inline bool GetThreadName(std::string&) {
return false;
}
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..45b1767
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,44 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This meson project only supports the Perfetto SDK
+# available from release branches.
+# https://perfetto.dev/docs/instrumentation/tracing-sdk
+
+project(
+ 'perfetto',
+ ['c','cpp'],
+ default_options: ['c_std=c99', 'cpp_std=c++11']
+)
+
+fs = import('fs')
+
+if not fs.is_dir('sdk')
+ error('sdk dir not found, please checkout a release tag, e.g. v13.0')
+endif
+
+dep_threads = dependency('threads')
+
+lib_perfetto = static_library(
+ 'perfetto',
+ sources: 'sdk/perfetto.cc',
+ dependencies: dep_threads,
+)
+
+inc_perfetto = include_directories('sdk')
+
+dep_perfetto = declare_dependency(
+ link_with: lib_perfetto,
+ include_directories: inc_perfetto,
+)
diff --git a/src/android_internal/power_stats.cc b/src/android_internal/power_stats.cc
index 7dff16c..34da342 100644
--- a/src/android_internal/power_stats.cc
+++ b/src/android_internal/power_stats.cc
@@ -16,6 +16,8 @@
#include "src/android_internal/power_stats.h"
+#include "perfetto/ext/base/utils.h"
+
#include <string.h>
#include <algorithm>
@@ -47,6 +49,8 @@
virtual bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) = 0;
// Available from Android S+.
+ virtual bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+ size_t* size_of_arr) = 0;
virtual bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
size_t* size_of_arr) = 0;
virtual ~PowerStatsDataProvider() = default;
@@ -56,6 +60,8 @@
public:
bool GetAvailableRails(RailDescriptor*, size_t* size_of_arr) override;
bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) override;
+ bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+ size_t* size_of_arr) override;
bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
size_t* size_of_arr) override;
@@ -74,6 +80,8 @@
bool GetAvailableRails(RailDescriptor*, size_t* size_of_arr) override;
bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) override;
+ bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+ size_t* size_of_arr) override;
bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
size_t* size_of_arr) override;
@@ -112,6 +120,10 @@
return GetDataProvider()->GetRailEnergyData(data, size_of_arr);
}
+bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers, size_t* size_of_arr) {
+ return GetDataProvider()->GetEnergyConsumerInfo(consumers, size_of_arr);
+}
+
bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
size_t* size_of_arr) {
return GetDataProvider()->GetEnergyConsumed(breakdown, size_of_arr);
@@ -198,6 +210,11 @@
return status == hal::Status::SUCCESS;
}
+bool PowerStatsHalDataProvider::GetEnergyConsumerInfo(EnergyConsumerInfo*,
+ size_t*) {
+ return false;
+}
+
bool PowerStatsHalDataProvider::GetEnergyConsumed(EnergyEstimationBreakdown*,
size_t*) {
return false;
@@ -288,6 +305,41 @@
return true;
}
+bool PowerStatsAidlDataProvider::GetEnergyConsumerInfo(
+ EnergyConsumerInfo* consumers,
+ size_t* size_of_arr) {
+ const size_t in_array_size = *size_of_arr;
+ *size_of_arr = 0;
+
+ aidl::IPowerStats* svc = MaybeGetService();
+ if (svc == nullptr) {
+ return false;
+ }
+ std::vector<aidl::EnergyConsumer> results;
+ android::binder::Status status = svc->getEnergyConsumerInfo(&results);
+
+ if (!status.isOk()) {
+ if (status.transactionError() == android::DEAD_OBJECT) {
+ // Service has died. Reset it to attempt to acquire a new one next time.
+ ResetService();
+ }
+ return false;
+ }
+ size_t max_size = std::min(in_array_size, results.size());
+ for (const auto& result : results) {
+ if (*size_of_arr >= max_size) {
+ break;
+ }
+ auto& cur = consumers[(*size_of_arr)++];
+ cur.energy_consumer_id = result.id;
+ cur.ordinal = result.ordinal;
+ strncpy(cur.type, aidl::toString(result.type).c_str(), sizeof(cur.type));
+ cur.type[sizeof(cur.type) - 1] = '\0';
+ strncpy(cur.name, result.name.c_str(), sizeof(cur.name));
+ cur.name[sizeof(cur.name) - 1] = '\0';
+ }
+ return true;
+}
bool PowerStatsAidlDataProvider::GetEnergyConsumed(
EnergyEstimationBreakdown* breakdown,
size_t* size_of_arr) {
diff --git a/src/android_internal/power_stats.h b/src/android_internal/power_stats.h
index c7693f9..3225d29 100644
--- a/src/android_internal/power_stats.h
+++ b/src/android_internal/power_stats.h
@@ -51,6 +51,24 @@
uint64_t energy;
};
+struct EnergyConsumerInfo {
+ // Unique ID of this energy consumer. Matches the ID in a
+ // EnergyEstimationBreakdown.
+ int32_t energy_consumer_id;
+
+ // For a group of energy consumers of the same logical type, sorting by
+ // ordinal gives their physical order. Ordinals must be consecutive integers
+ // starting from 0.
+ int32_t ordinal;
+
+ // Type of this energy consumer.
+ char type[64];
+
+ // Unique name of this energy consumer. Vendor/device specific. Opaque to
+ // framework.
+ char name[64];
+};
+
struct EnergyEstimationBreakdown {
// Energy consumer ID.
int32_t energy_consumer_id;
@@ -73,6 +91,9 @@
bool __attribute__((visibility("default")))
GetRailEnergyData(RailEnergyData*, size_t* size_of_arr);
+bool __attribute__((visibility("default")))
+GetEnergyConsumerInfo(EnergyConsumerInfo* consumers, size_t* size_of_arr);
+
// Retrieve the energy estimation breakdown for all energy consumer. For each
// consumer, there will be an entry with a uid of ALL_UIDS_FOR_CONSUMER,
// followed by the energy breakdown for each process contributing to that
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index f45e348..fa1527d 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -75,7 +75,8 @@
size_t n) {
std::vector<UnwindingWorker> ret;
for (size_t i = 0; i < n; ++i) {
- ret.emplace_back(delegate, base::ThreadTaskRunner::CreateAndStart());
+ ret.emplace_back(delegate,
+ base::ThreadTaskRunner::CreateAndStart("heapprofdunwind"));
}
return ret;
}
diff --git a/src/traced/probes/power/BUILD.gn b/src/traced/probes/power/BUILD.gn
index 7b75c6a..fc28f67 100644
--- a/src/traced/probes/power/BUILD.gn
+++ b/src/traced/probes/power/BUILD.gn
@@ -18,6 +18,7 @@
"..:data_source",
"../../../../gn:default_deps",
"../../../../include/perfetto/ext/traced",
+ "../../../../protos/perfetto/common:zero",
"../../../../protos/perfetto/config/power:zero",
"../../../../protos/perfetto/trace:zero",
"../../../../protos/perfetto/trace/power:zero",
diff --git a/src/traced/probes/power/android_power_data_source.cc b/src/traced/probes/power/android_power_data_source.cc
index 85a0daa..0034453 100644
--- a/src/traced/probes/power/android_power_data_source.cc
+++ b/src/traced/probes/power/android_power_data_source.cc
@@ -30,6 +30,7 @@
#include "src/android_internal/lazy_library_loader.h"
#include "src/android_internal/power_stats.h"
+#include "protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h"
#include "protos/perfetto/config/power/android_power_config.pbzero.h"
#include "protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h"
#include "protos/perfetto/trace/power/battery_counters.pbzero.h"
@@ -41,6 +42,7 @@
namespace {
constexpr uint32_t kMinPollIntervalMs = 100;
constexpr size_t kMaxNumRails = 32;
+constexpr size_t kMaxNumEnergyConsumer = 32;
constexpr size_t kMaxNumPowerEntities = 256;
} // namespace
@@ -57,6 +59,8 @@
PERFETTO_LAZY_LOAD(android_internal::GetAvailableRails, get_available_rails_);
PERFETTO_LAZY_LOAD(android_internal::GetRailEnergyData,
get_rail_energy_data_);
+ PERFETTO_LAZY_LOAD(android_internal::GetEnergyConsumerInfo,
+ get_energy_consumer_info_);
PERFETTO_LAZY_LOAD(android_internal::GetEnergyConsumed, get_energy_consumed_);
base::Optional<int64_t> GetCounter(android_internal::BatteryCounter counter) {
@@ -97,6 +101,21 @@
return energy_data;
}
+ std::vector<android_internal::EnergyConsumerInfo> GetEnergyConsumerInfo() {
+ if (!get_energy_consumer_info_)
+ return std::vector<android_internal::EnergyConsumerInfo>();
+
+ std::vector<android_internal::EnergyConsumerInfo> consumers(
+ kMaxNumEnergyConsumer);
+ size_t num_power_entities = consumers.size();
+ if (!get_energy_consumer_info_(&consumers[0], &num_power_entities)) {
+ PERFETTO_ELOG("Failed to retrieve energy consumer info.");
+ num_power_entities = 0;
+ }
+ consumers.resize(num_power_entities);
+ return consumers;
+ }
+
std::vector<android_internal::EnergyEstimationBreakdown> GetEnergyConsumed() {
if (!get_energy_consumed_)
return std::vector<android_internal::EnergyEstimationBreakdown>();
@@ -121,6 +140,7 @@
: ProbesDataSource(session_id, &descriptor),
task_runner_(task_runner),
rail_descriptors_logged_(false),
+ energy_consumer_loggged_(false),
writer_(std::move(writer)),
weak_factory_(this) {
using protos::pbzero::AndroidPowerConfig;
@@ -261,12 +281,29 @@
void AndroidPowerDataSource::WriteEnergyEstimationBreakdown() {
if (!energy_breakdown_collection_enabled_)
return;
- auto energy_breakdowns = lib_->GetEnergyConsumed();
auto timestamp = static_cast<uint64_t>(base::GetBootTimeNs().count());
TraceWriter::TracePacketHandle packet;
protos::pbzero::AndroidEnergyEstimationBreakdown* energy_estimation_proto =
nullptr;
+
+ if (!energy_consumer_loggged_) {
+ energy_consumer_loggged_ = true;
+ packet = writer_->NewTracePacket();
+ energy_estimation_proto = packet->set_android_energy_estimation_breakdown();
+ auto* descriptor_proto =
+ energy_estimation_proto->set_energy_consumer_descriptor();
+ auto consumers = lib_->GetEnergyConsumerInfo();
+ for (const auto& consumer : consumers) {
+ auto* desc_proto = descriptor_proto->add_energy_consumers();
+ desc_proto->set_energy_consumer_id(consumer.energy_consumer_id);
+ desc_proto->set_ordinal(consumer.ordinal);
+ desc_proto->set_type(consumer.type);
+ desc_proto->set_name(consumer.name);
+ }
+ }
+
+ auto energy_breakdowns = lib_->GetEnergyConsumed();
for (const auto& breakdown : energy_breakdowns) {
if (breakdown.uid == android_internal::ALL_UIDS_FOR_CONSUMER) {
// Finalize packet before calling NewTracePacket.
diff --git a/src/traced/probes/power/android_power_data_source.h b/src/traced/probes/power/android_power_data_source.h
index 9841fa8..4fecfda 100644
--- a/src/traced/probes/power/android_power_data_source.h
+++ b/src/traced/probes/power/android_power_data_source.h
@@ -62,6 +62,7 @@
std::bitset<8> counters_enabled_;
bool rails_collection_enabled_;
bool rail_descriptors_logged_;
+ bool energy_consumer_loggged_;
bool energy_breakdown_collection_enabled_;
std::unique_ptr<TraceWriter> writer_;
std::unique_ptr<DynamicLibLoader> lib_;