Merge "Fix clang-tidy performance warnings in libfec."
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 6957767..c24042a 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -78,7 +78,8 @@
"record", "record sampling info in perf.data",
// clang-format off
"Usage: simpleperf record [options] [command [command-args]]\n"
-" Gather sampling information when running [command].\n"
+" Gather sampling information of running [command]. And -a/-p/-t option\n"
+" can be used to change target of sampling information.\n"
"-a System-wide collection.\n"
"-b Enable take branch stack sampling. Same as '-j any'\n"
"-c count Set event sample period. It means recording one sample when\n"
@@ -94,6 +95,9 @@
"--dump-symbols Dump symbols in perf.data. By default perf.data doesn't contain\n"
" symbol information for samples. This option is used when there\n"
" is no symbol information in report environment.\n"
+"--duration time_in_sec Monitor for time_in_sec seconds instead of running\n"
+" [command]. Here time_in_sec may be any positive\n"
+" floating point number.\n"
"-e event1[:modifier1],event2[:modifier2],...\n"
" Select the event list to sample. Use `simpleperf list` to find\n"
" all possible event names. Modifiers can be added to define how\n"
@@ -342,6 +346,7 @@
bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
std::vector<std::string>* non_option_args) {
std::set<pid_t> tid_set;
+ double duration_in_sec = 0;
size_t i;
for (i = 0; i < args.size() && !args[i].empty() && args[i][0] == '-'; ++i) {
if (args[i] == "-a") {
@@ -403,6 +408,17 @@
cpus_ = GetCpusFromString(args[i]);
} else if (args[i] == "--dump-symbols") {
dump_symbols_ = true;
+ } else if (args[i] == "--duration") {
+ if (!NextArgumentOrError(args, &i)) {
+ return false;
+ }
+ errno = 0;
+ char* endptr;
+ duration_in_sec = strtod(args[i].c_str(), &endptr);
+ if (duration_in_sec <= 0 || *endptr != '\0' || errno == ERANGE) {
+ LOG(ERROR) << "Invalid duration: " << args[i].c_str();
+ return false;
+ }
} else if (args[i] == "-e") {
if (!NextArgumentOrError(args, &i)) {
return false;
@@ -544,11 +560,19 @@
can_dump_kernel_symbols_ = false;
}
- if (non_option_args != nullptr) {
- non_option_args->clear();
- for (; i < args.size(); ++i) {
- non_option_args->push_back(args[i]);
+ non_option_args->clear();
+ for (; i < args.size(); ++i) {
+ non_option_args->push_back(args[i]);
+ }
+ if (duration_in_sec != 0) {
+ if (!non_option_args->empty()) {
+ LOG(ERROR) << "Using --duration option while running a command is not "
+ "supported.";
+ return false;
}
+ non_option_args->insert(
+ non_option_args->end(),
+ {"sleep", android::base::StringPrintf("%f", duration_in_sec)});
}
return true;
}
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index afd5bdd..8a750a6 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -313,3 +313,8 @@
}
TEST(record_cmd, symfs_option) { ASSERT_TRUE(RunRecordCmd({"--symfs", "/"})); }
+
+TEST(record_cmd, duration_option) {
+ TemporaryFile tmpfile;
+ ASSERT_TRUE(RecordCmd()->Run({"--duration", "1.2", "-o", tmpfile.path}));
+}
diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp
index 9c407d3..e27fa99 100644
--- a/simpleperf/cmd_report_sample.cpp
+++ b/simpleperf/cmd_report_sample.cpp
@@ -78,7 +78,10 @@
use_protobuf_(false),
report_fp_(nullptr),
coded_os_(nullptr),
- sample_count_(0) {}
+ sample_count_(0) {
+ thread_tree_.ShowMarkForUnknownSymbol();
+ thread_tree_.ShowIpForUnknownSymbol();
+ }
bool Run(const std::vector<std::string>& args) override;
diff --git a/simpleperf/cmd_report_test.cpp b/simpleperf/cmd_report_test.cpp
index d6231bf..e0b35bf 100644
--- a/simpleperf/cmd_report_test.cpp
+++ b/simpleperf/cmd_report_test.cpp
@@ -159,7 +159,7 @@
TEST_F(ReportCommandTest, callgraph_option) {
Report(CALLGRAPH_FP_PERF_DATA, {"-g"});
ASSERT_TRUE(success);
- ASSERT_TRUE(CheckCalleeMode(lines));
+ ASSERT_TRUE(CheckCallerMode(lines));
Report(CALLGRAPH_FP_PERF_DATA, {"-g", "callee"});
ASSERT_TRUE(success);
ASSERT_TRUE(CheckCalleeMode(lines));
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index f5792f8..42be557 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -125,7 +125,7 @@
class CounterSummaries {
public:
- explicit CounterSummaries(bool csv): csv_(csv) {}
+ explicit CounterSummaries(bool csv) : csv_(csv) {}
void AddSummary(const CounterSummary& summary) {
summaries_.push_back(summary);
}
@@ -153,7 +153,8 @@
if (other != nullptr && other->IsMonitoredAtTheSameTime(s)) {
if (FindSummary(s.type_name, "") == nullptr) {
AddSummary(CounterSummary(s.type_name, "", s.group_id,
- s.count + other->count, s.scale, true, csv_));
+ s.count + other->count, s.scale, true,
+ csv_));
}
}
}
@@ -179,11 +180,9 @@
for (auto& s : summaries_) {
if (csv_) {
- fprintf(fp, "%s,%s,%s,(%.0lf%%)%s\n",
- s.readable_count.c_str(),
- s.Name().c_str(),
- s.comment.c_str(),
- 1.0 / s.scale * 100, (s.auto_generated ? " (generated)," : ","));
+ fprintf(fp, "%s,%s,%s,(%.0lf%%)%s\n", s.readable_count.c_str(),
+ s.Name().c_str(), s.comment.c_str(), 1.0 / s.scale * 100,
+ (s.auto_generated ? " (generated)," : ","));
} else {
fprintf(fp, " %*s %-*s # %-*s (%.0lf%%)%s\n",
static_cast<int>(count_column_width), s.readable_count.c_str(),
@@ -219,7 +218,8 @@
const CounterSummary* other = FindSummary("cpu-cycles", s.modifier);
if (other != nullptr && other->IsMonitoredAtTheSameTime(s)) {
double cpi = static_cast<double>(other->count) / s.count;
- return android::base::StringPrintf("%lf%ccycles per instruction", cpi, sap_mid);
+ return android::base::StringPrintf("%lf%ccycles per instruction", cpi,
+ sap_mid);
}
}
if (android::base::EndsWith(s.type_name, "-misses")) {
@@ -236,7 +236,8 @@
if (other != nullptr && other->IsMonitoredAtTheSameTime(s) &&
other->count != 0) {
double miss_rate = static_cast<double>(s.count) / other->count;
- return android::base::StringPrintf("%lf%%%cmiss rate", miss_rate * 100, sap_mid);
+ return android::base::StringPrintf("%lf%%%cmiss rate", miss_rate * 100,
+ sap_mid);
}
}
double rate = s.count / (duration_in_sec / s.scale);
@@ -260,16 +261,19 @@
class StatCommand : public Command {
public:
StatCommand()
- : Command(
- "stat", "gather performance counter information",
- // clang-format off
+ : Command("stat", "gather performance counter information",
+ // clang-format off
"Usage: simpleperf stat [options] [command [command-args]]\n"
-" Gather performance counter information of running [command].\n"
+" Gather performance counter information of running [command].\n"
+" And -a/-p/-t option can be used to change target of counter information.\n"
"-a Collect system-wide information.\n"
"--cpu cpu_item1,cpu_item2,...\n"
" Collect information only on the selected cpus. cpu_item can\n"
" be a cpu number like 1, or a cpu range like 0-3.\n"
"--csv Write report in comma separate form.\n"
+"--duration time_in_sec Monitor for time_in_sec seconds instead of running\n"
+" [command]. Here time_in_sec may be any positive\n"
+" floating point number.\n"
"-e event1[:modifier1],event2[:modifier2],...\n"
" Select the event list to count. Use `simpleperf list` to find\n"
" all possible event names. Modifiers can be added to define\n"
@@ -285,8 +289,8 @@
"-p pid1,pid2,... Stat events on existing processes. Mutually exclusive with -a.\n"
"-t tid1,tid2,... Stat events on existing threads. Mutually exclusive with -a.\n"
"--verbose Show result in verbose mode.\n"
- // clang-format on
- ),
+ // clang-format on
+ ),
verbose_mode_(false),
system_wide_collection_(false),
child_inherit_(true),
@@ -399,6 +403,7 @@
bool StatCommand::ParseOptions(const std::vector<std::string>& args,
std::vector<std::string>* non_option_args) {
std::set<pid_t> tid_set;
+ double duration_in_sec = 0;
size_t i;
for (i = 0; i < args.size() && args[i].size() > 0 && args[i][0] == '-'; ++i) {
if (args[i] == "-a") {
@@ -410,6 +415,17 @@
cpus_ = GetCpusFromString(args[i]);
} else if (args[i] == "--csv") {
csv_ = true;
+ } else if (args[i] == "--duration") {
+ if (!NextArgumentOrError(args, &i)) {
+ return false;
+ }
+ errno = 0;
+ char* endptr;
+ duration_in_sec = strtod(args[i].c_str(), &endptr);
+ if (duration_in_sec <= 0 || *endptr != '\0' || errno == ERANGE) {
+ LOG(ERROR) << "Invalid duration: " << args[i].c_str();
+ return false;
+ }
} else if (args[i] == "-e") {
if (!NextArgumentOrError(args, &i)) {
return false;
@@ -464,12 +480,24 @@
"used at the same time.";
return false;
}
+ if (system_wide_collection_ && !IsRoot()) {
+ LOG(ERROR) << "System wide profiling needs root privilege.";
+ return false;
+ }
- if (non_option_args != nullptr) {
- non_option_args->clear();
- for (; i < args.size(); ++i) {
- non_option_args->push_back(args[i]);
+ non_option_args->clear();
+ for (; i < args.size(); ++i) {
+ non_option_args->push_back(args[i]);
+ }
+ if (duration_in_sec != 0) {
+ if (!non_option_args->empty()) {
+ LOG(ERROR) << "Using --duration option while running a command is not "
+ "supported.";
+ return false;
}
+ non_option_args->insert(
+ non_option_args->end(),
+ {"sleep", android::base::StringPrintf("%f", duration_in_sec)});
}
return true;
}
@@ -521,9 +549,8 @@
counters_info.selection->event_type_modifier;
for (auto& counter_info : counters_info.counters) {
if (csv_) {
- fprintf(fp,
- "%s,tid,%d,cpu,%d,count,%" PRIu64 ",time_enabled,%" PRIu64
- ",time running,%" PRIu64 ",id,%" PRIu64 ",\n",
+ fprintf(fp, "%s,tid,%d,cpu,%d,count,%" PRIu64 ",time_enabled,%" PRIu64
+ ",time running,%" PRIu64 ",id,%" PRIu64 ",\n",
event_type.name.c_str(), counter_info.tid, counter_info.cpu,
counter_info.counter.value, counter_info.counter.time_enabled,
counter_info.counter.time_running, counter_info.counter.id);
diff --git a/simpleperf/cmd_stat_test.cpp b/simpleperf/cmd_stat_test.cpp
index 4d63498..2610926 100644
--- a/simpleperf/cmd_stat_test.cpp
+++ b/simpleperf/cmd_stat_test.cpp
@@ -109,3 +109,7 @@
// Check if the summary of cpu-clock is generated.
ASSERT_NE(s.npos, s.find("cpu-clock", pos));
}
+
+TEST(stat_cmd, duration_option) {
+ ASSERT_TRUE(StatCmd()->Run({"--duration", "1.2"}));
+}
diff --git a/simpleperf/runtest/function_fork.cpp b/simpleperf/runtest/function_fork.cpp
index b813702..b1477a6 100644
--- a/simpleperf/runtest/function_fork.cpp
+++ b/simpleperf/runtest/function_fork.cpp
@@ -1,14 +1,20 @@
+#include <stdlib.h>
#include <unistd.h>
constexpr int LOOP_COUNT = 100000000;
+volatile int a[2];
void ParentFunction() {
- for (volatile int i = 0; i < LOOP_COUNT; ++i) {
+ volatile int* p = a + atoi("0");
+ for (int i = 0; i < LOOP_COUNT; ++i) {
+ *p = i;
}
}
void ChildFunction() {
- for (volatile int i = 0; i < LOOP_COUNT; ++i) {
+ volatile int* p = a + atoi("1");
+ for (int i = 0; i < LOOP_COUNT; ++i) {
+ *p = i;
}
}
diff --git a/simpleperf/runtest/runtest.py b/simpleperf/runtest/runtest.py
index e4cc0d2..33a3a6c 100644
--- a/simpleperf/runtest/runtest.py
+++ b/simpleperf/runtest/runtest.py
@@ -25,6 +25,8 @@
The information of all runtests is stored in runtest.conf.
"""
+import os
+import os.path
import re
import subprocess
import sys
@@ -314,6 +316,11 @@
"""Run perf test on device."""
+ def __init__(self, perf_path):
+ self._download(os.environ['OUT'] + '/system/xbin/' + perf_path,
+ '/data/local/tmp')
+ self.perf_path = '/data/local/tmp/' + perf_path
+
def _call(self, args, output_file=None):
output_fh = None
if output_file is not None:
@@ -324,6 +331,15 @@
if output_fh is not None:
output_fh.close()
+ def _download(self, file, to_dir):
+ args = ['adb', 'push', file, to_dir]
+ subprocess.check_call(args)
+
+ def record(self, test_executable_name, record_file, additional_options=[]):
+ self._download(os.environ['OUT'] + '/system/bin/' + test_executable_name,
+ '/data/local/tmp')
+ super(DeviceRunner, self).record('/data/local/tmp/' + test_executable_name,
+ record_file, additional_options)
class ReportAnalyzer(object):
@@ -497,7 +513,8 @@
def runtest(host, device, normal, callgraph, selected_tests):
- tests = load_config_file('runtest.conf')
+ tests = load_config_file(os.path.dirname(os.path.realpath(__file__)) + \
+ '/runtest.conf')
host_runner = HostRunner('simpleperf')
device_runner = DeviceRunner('simpleperf')
report_analyzer = ReportAnalyzer()
@@ -530,11 +547,11 @@
host_runner.record(
test.executable_name,
'perf_g.data',
- additional_options=['-g'])
+ additional_options=['-g', '-f', '1000'])
host_runner.report(
'perf_g.data',
'perf_g.report',
- additional_options=['-g'] + test.report_options)
+ additional_options=['-g', 'callee'] + test.report_options)
result = report_analyzer.check_report_file(test, 'perf_g.report', True)
print 'call-graph test %s on host %s' % (
test.test_name, 'Succeeded' if result else 'Failed')
@@ -542,14 +559,16 @@
exit(1)
if device and callgraph:
+ # Decrease sampling frequency by -f 1000 to avoid losing records
+ # while recording call-graph.
device_runner.record(
test.executable_name,
'/data/perf_g.data',
- additional_options=['-g'])
+ additional_options=['-g', '-f', '1000'])
device_runner.report(
'/data/perf_g.data',
'perf_g.report',
- additional_options=['-g'] + test.report_options)
+ additional_options=['-g', 'callee'] + test.report_options)
result = report_analyzer.check_report_file(test, 'perf_g.report', True)
print 'call-graph test %s on device %s' % (
test.test_name, 'Succeeded' if result else 'Failed')
diff --git a/simpleperf/runtest/two_functions.cpp b/simpleperf/runtest/two_functions.cpp
index 1511102..1d3e389 100644
--- a/simpleperf/runtest/two_functions.cpp
+++ b/simpleperf/runtest/two_functions.cpp
@@ -1,12 +1,19 @@
+#include <stdlib.h>
+
constexpr int LOOP_COUNT = 100000000;
+volatile int a[2];
void Function1() {
- for (volatile int i = 0; i < LOOP_COUNT; ++i) {
+ volatile int* p = a + atoi("0");
+ for (int i = 0; i < LOOP_COUNT; ++i) {
+ *p = i;
}
}
void Function2() {
- for (volatile int i = 0; i < LOOP_COUNT; ++i) {
+ volatile int* p = a + atoi("1");
+ for (int i = 0; i < LOOP_COUNT; ++i) {
+ *p = i;
}
}
diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp
index fafefa0..3a20ee7 100644
--- a/simpleperf/thread_tree.cpp
+++ b/simpleperf/thread_tree.cpp
@@ -228,7 +228,9 @@
if (symbol == nullptr) {
if (show_ip_for_unknown_symbol_) {
std::string name = android::base::StringPrintf(
- "%s[+%" PRIx64 "]", dso->FileName().c_str(), vaddr_in_file);
+ "%s%s[+%" PRIx64 "]",
+ (show_mark_for_unknown_symbol_ ? "*" : ""),
+ dso->FileName().c_str(), vaddr_in_file);
dso->InsertSymbol(Symbol(name, vaddr_in_file, 1));
symbol = dso->FindSymbol(vaddr_in_file);
CHECK(symbol != nullptr);
diff --git a/simpleperf/thread_tree.h b/simpleperf/thread_tree.h
index a8d3fa0..5498df5 100644
--- a/simpleperf/thread_tree.h
+++ b/simpleperf/thread_tree.h
@@ -69,6 +69,7 @@
public:
ThreadTree()
: show_ip_for_unknown_symbol_(false),
+ show_mark_for_unknown_symbol_(false),
unknown_symbol_("unknown", 0,
std::numeric_limits<unsigned long long>::max()) {
unknown_dso_ = Dso::CreateDso(DSO_ELF_FILE, "unknown");
@@ -94,6 +95,10 @@
const Symbol* UnknownSymbol() const { return &unknown_symbol_; }
void ShowIpForUnknownSymbol() { show_ip_for_unknown_symbol_ = true; }
+ void ShowMarkForUnknownSymbol() {
+ show_mark_for_unknown_symbol_ = true;
+ unknown_symbol_ = Symbol("*unknown", 0, ULLONG_MAX);
+ }
// Clear thread and map information, but keep loaded dso information. It saves
// the time to reload dso information.
void ClearThreadAndMap();
@@ -120,6 +125,7 @@
std::unordered_map<std::string, std::unique_ptr<Dso>> user_dso_tree_;
std::unique_ptr<Dso> unknown_dso_;
bool show_ip_for_unknown_symbol_;
+ bool show_mark_for_unknown_symbol_;
Symbol unknown_symbol_;
std::unordered_map<uint64_t, Dso*> dso_id_to_dso_map_;
};
diff --git a/verity/Android.mk b/verity/Android.mk
index ffa4a2c..1a7351f 100644
--- a/verity/Android.mk
+++ b/verity/Android.mk
@@ -7,7 +7,7 @@
LOCAL_SRC_FILES := verify_boot_signature.c
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libcrypto-host
+LOCAL_SHARED_LIBRARIES := libcrypto
LOCAL_C_INCLUDES += external/openssl/include system/extras/ext4_utils system/core/mkbootimg
include $(BUILD_HOST_EXECUTABLE)
@@ -18,7 +18,7 @@
LOCAL_SRC_FILES := generate_verity_key.c
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto-host
+LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto
include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
@@ -85,7 +85,7 @@
LOCAL_SRC_FILES := build_verity_tree.cpp
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libsparse_host libz
-LOCAL_SHARED_LIBRARIES := libcrypto-host libbase
+LOCAL_SHARED_LIBRARIES := libcrypto libbase
LOCAL_CFLAGS += -Wall -Werror
include $(BUILD_HOST_EXECUTABLE)