diff options
author | Andreas Gampe <agampe@google.com> | 2018-08-03 12:51:46 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-08-03 12:51:46 -0700 |
commit | 513cbfa0aebc55d39eeb72c2528e583dd7c3ffbe (patch) | |
tree | 48497f82572d7808b62e70492854b80e1b20a2be /perfprofd | |
parent | d89ea0f6e6fba226057a2bd8d077395d85730b81 (diff) | |
parent | d4e3b2199be1e909698ce4911daf26035ca1bcda (diff) | |
download | extras-513cbfa0aebc55d39eeb72c2528e583dd7c3ffbe.tar.gz |
Merge "Perfprofd: Add option dump"
am: d4e3b2199b
Change-Id: Icda6762aa4551ce1fb3038ffa2e0905d701780d5
Diffstat (limited to 'perfprofd')
-rw-r--r-- | perfprofd/binder_interface/perfprofd_binder.cc | 10 | ||||
-rw-r--r-- | perfprofd/configreader.cc | 103 | ||||
-rw-r--r-- | perfprofd/configreader.h | 1 | ||||
-rw-r--r-- | perfprofd/perfprofd_threaded_handler.h | 6 | ||||
-rw-r--r-- | perfprofd/tests/perfprofd_test.cc | 53 |
5 files changed, 172 insertions, 1 deletions
diff --git a/perfprofd/binder_interface/perfprofd_binder.cc b/perfprofd/binder_interface/perfprofd_binder.cc index ef7de6dd..a1c77e24 100644 --- a/perfprofd/binder_interface/perfprofd_binder.cc +++ b/perfprofd/binder_interface/perfprofd_binder.cc @@ -108,7 +108,15 @@ status_t PerfProfdNativeService::start() { status_t PerfProfdNativeService::dump(int fd, const Vector<String16> &args) { auto out = std::fstream(base::StringPrintf("/proc/self/fd/%d", fd)); - out << "Nothing to log, yet!" << std::endl; + auto print_config = [&out](bool is_profiling, const Config* config) { + if (is_profiling) { + out << "Profiling with config: " << ConfigReader::ConfigToString(*config); + } else { + out << "Not actively profiling."; + } + }; + RunOnConfig(print_config); + out << std::endl; return NO_ERROR; } diff --git a/perfprofd/configreader.cc b/perfprofd/configreader.cc index c5442777..44111943 100644 --- a/perfprofd/configreader.cc +++ b/perfprofd/configreader.cc @@ -463,6 +463,109 @@ void ConfigReader::FillConfig(Config* config) { } } +namespace { + +template <typename T> +struct OssFormatter { +}; + +template <> +struct OssFormatter<std::string> { + void Add(std::ostream& os, const std::string& val) { + os << val; + } +}; + +template <> +struct OssFormatter<uint32_t> { + void Add(std::ostream& os, const uint32_t& val) { + os << val; + } +}; + +template <> +struct OssFormatter<int32_t> { + void Add(std::ostream& os, const int32_t& val) { + os << val; + } +}; + +template <> +struct OssFormatter<bool> { + void Add(std::ostream& os, const bool& val) { + os << (val ? 1 : 0); + } +}; + + +} // namespace + +std::string ConfigReader::ConfigToString(const Config& config) { + std::ostringstream oss; + + auto add = [&oss](const char* str, auto val) { + if (oss.tellp() != 0) { + oss << ' '; + } + oss << str << '='; + OssFormatter<decltype(val)> fmt; + fmt.Add(oss, val); + }; + + add("collection_interval", config.collection_interval_in_s); + add("use_fixed_seed", config.use_fixed_seed); + add("main_loop_iterations", config.main_loop_iterations); + + add("destination_directory", config.destination_directory); // TODO: Escape. + add("config_directory", config.config_directory); // TODO: Escape. + add("perf_path", config.perf_path); // TODO: Escape. + + add("sampling_period", config.sampling_period); + add("sampling_frequency", config.sampling_frequency); + + add("sample_duration", config.sample_duration_in_s); + + add("only_debug_build", config.only_debug_build); + + add("hardwire_cpus", config.hardwire_cpus); + + add("hardwire_cpus_max_duration", config.hardwire_cpus_max_duration_in_s); + + add("max_unprocessed_profiles", config.max_unprocessed_profiles); + + add("stack_profile", config.stack_profile); + + add("trace_config_read", config.trace_config_read); + + add("collect_cpu_utilization", config.collect_cpu_utilization); + add("collect_charging_state", config.collect_charging_state); + add("collect_booting", config.collect_booting); + add("collect_camera_active", config.collect_camera_active); + + add("process", config.process); + add("use_elf_symbolizer", config.use_elf_symbolizer); + add("symbolize_everything", config.symbolize_everything); + add("compress", config.compress); + add("dropbox", config.send_to_dropbox); + add("fail_on_unsupported_events", config.fail_on_unsupported_events); + + for (const auto& elem : config.event_config) { + std::ostringstream oss_elem; + oss_elem << '-' << (elem.group ? 'g' : 'e') << '_'; + bool first = true; + for (const auto& event : elem.events) { + if (!first) { + oss_elem << ','; + } + oss_elem << event; + first = false; + } + add(oss_elem.str().c_str(), elem.sampling_period); + } + + return oss.str(); +} + void ConfigReader::ProtoToConfig(const android::perfprofd::ProfilingConfig& in, Config* out) { // Copy base proto values. #define CHECK_AND_COPY_FROM_PROTO(name) \ diff --git a/perfprofd/configreader.h b/perfprofd/configreader.h index 180e537e..3d2243c5 100644 --- a/perfprofd/configreader.h +++ b/perfprofd/configreader.h @@ -60,6 +60,7 @@ class ConfigReader { void overrideUnsignedEntry(const char *key, unsigned new_value); void FillConfig(Config* config); + static std::string ConfigToString(const Config& config); static void ProtoToConfig(const android::perfprofd::ProfilingConfig& in, Config* out); diff --git a/perfprofd/perfprofd_threaded_handler.h b/perfprofd/perfprofd_threaded_handler.h index 037e24cc..76cdd67a 100644 --- a/perfprofd/perfprofd_threaded_handler.h +++ b/perfprofd/perfprofd_threaded_handler.h @@ -170,6 +170,12 @@ class ThreadedHandler { return true; } + template <typename Fn> + void RunOnConfig(Fn& fn) { + std::lock_guard<std::mutex> guard(lock_); + fn(cur_config_->is_profiling, cur_config_.get()); + } + private: // Helper for the handler. HandlerFn GetResultHandler() { diff --git a/perfprofd/tests/perfprofd_test.cc b/perfprofd/tests/perfprofd_test.cc index 09392054..a26694c7 100644 --- a/perfprofd/tests/perfprofd_test.cc +++ b/perfprofd/tests/perfprofd_test.cc @@ -712,6 +712,59 @@ TEST_F(PerfProfdTest, ConfigFileParsing_Events) { } } + +TEST_F(PerfProfdTest, ConfigDump) { + constexpr const char* kConfigElems[] = { + "collection_interval=14400", + "use_fixed_seed=1", + "main_loop_iterations=2", + "destination_directory=/does/not/exist", + "config_directory=a", + "perf_path=/system/xbin/simpleperf2", + "sampling_period=3", + "sampling_frequency=4", + "sample_duration=5", + "only_debug_build=1", + "hardwire_cpus=1", + "hardwire_cpus_max_duration=6", + "max_unprocessed_profiles=7", + "stack_profile=1", + "trace_config_read=1", + "collect_cpu_utilization=1", + "collect_charging_state=1", + "collect_booting=1", + "collect_camera_active=1", + "process=8", + "use_elf_symbolizer=1", + "symbolize_everything=1", + "compress=1", + "dropbox=1", + "fail_on_unsupported_events=1", + "-e_hello,world=1", + "-g_foo,bar=2", + "-e_abc,xyz=3", + "-g_ftrace:test,ftrace:test2=4", + }; + + std::string input; + for (const char* elem : kConfigElems) { + input.append(elem); + input.append("\n"); + } + + ConfigReader reader; + std::string error_msg; + ASSERT_TRUE(reader.Read(input, false, &error_msg)) << error_msg; + + PerfProfdRunner::LoggingConfig config; + reader.FillConfig(&config); + + std::string output = ConfigReader::ConfigToString(config); + for (const char* elem : kConfigElems) { + EXPECT_TRUE(output.find(elem) != std::string::npos) << elem << " not in " << output; + } +} + TEST_F(PerfProfdTest, ProfileCollectionAnnotations) { unsigned util1 = collect_cpu_utilization(); |