diff options
author | Yabin Cui <yabinc@google.com> | 2017-01-30 11:34:24 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2017-02-03 10:37:38 -0800 |
commit | 26968e6c48dea2eaa217991ade5a04e801f1be8f (patch) | |
tree | 015ed7af1aed3135a10bc647c0db08ea8759a63a /simpleperf/runtest | |
parent | a284424d6cf9396e680e01dd86c50864d55365cf (diff) | |
download | extras-26968e6c48dea2eaa217991ade5a04e801f1be8f.tar.gz |
simpleperf: add inplace-sampler event type.
Add inplace-sampler event type, so it can be used in
record/list command. This cl doesn't add code for communicating
with profiled process, and fake records in InplaceSamplerClient.cpp
for testing purpose.
Refactor runtest.py to test inplace-sampler profiling.
Bug: http://b/30974760
Test: run runtest.py --inplace-sampler.
Change-Id: I92d8b03583c58b3589207f5c655e03853899be3a
Diffstat (limited to 'simpleperf/runtest')
-rw-r--r-- | simpleperf/runtest/comm_change.cpp | 13 | ||||
-rw-r--r-- | simpleperf/runtest/function_fork.cpp | 16 | ||||
-rw-r--r-- | simpleperf/runtest/function_indirect_recursive.cpp | 4 | ||||
-rw-r--r-- | simpleperf/runtest/function_pthread.cpp | 24 | ||||
-rw-r--r-- | simpleperf/runtest/function_recursive.cpp | 4 | ||||
-rw-r--r-- | simpleperf/runtest/one_function.cpp | 4 | ||||
-rw-r--r-- | simpleperf/runtest/runtest.py | 110 | ||||
-rw-r--r-- | simpleperf/runtest/two_functions.cpp | 6 |
8 files changed, 130 insertions, 51 deletions
diff --git a/simpleperf/runtest/comm_change.cpp b/simpleperf/runtest/comm_change.cpp index 12d64fa2..cdcb2bf4 100644 --- a/simpleperf/runtest/comm_change.cpp +++ b/simpleperf/runtest/comm_change.cpp @@ -8,9 +8,14 @@ void Function1() { } int main() { - prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM1"), 0, 0, 0); // NOLINT - Function1(); - prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM2"), 0, 0, 0); // NOLINT - Function1(); + // Run the test in an infinite loop, so if we profile the test manually, the process + // doesn't exit before we attach to it. This scheme also allows simpleperf to control + // how long to profile. + while (true) { + prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM1"), 0, 0, 0); // NOLINT + Function1(); + prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("RUN_COMM2"), 0, 0, 0); // NOLINT + Function1(); + } return 0; } diff --git a/simpleperf/runtest/function_fork.cpp b/simpleperf/runtest/function_fork.cpp index b1477a6a..8551927d 100644 --- a/simpleperf/runtest/function_fork.cpp +++ b/simpleperf/runtest/function_fork.cpp @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <sys/wait.h> #include <unistd.h> constexpr int LOOP_COUNT = 100000000; @@ -19,12 +20,15 @@ void ChildFunction() { } int main() { - pid_t pid = fork(); - if (pid == 0) { - ChildFunction(); - return 0; - } else { - ParentFunction(); + while (true) { + pid_t pid = fork(); + if (pid == 0) { + ChildFunction(); + return 0; + } else { + ParentFunction(); + waitpid(pid, nullptr, 0); + } } return 0; } diff --git a/simpleperf/runtest/function_indirect_recursive.cpp b/simpleperf/runtest/function_indirect_recursive.cpp index 5e70fd32..70645a1b 100644 --- a/simpleperf/runtest/function_indirect_recursive.cpp +++ b/simpleperf/runtest/function_indirect_recursive.cpp @@ -19,6 +19,8 @@ void FunctionRecursiveTwo(int loop) { } int main() { - FunctionRecursiveOne(10); + while (true) { + FunctionRecursiveOne(10); + } return 0; } diff --git a/simpleperf/runtest/function_pthread.cpp b/simpleperf/runtest/function_pthread.cpp index 02fc0a5f..c80fb3f2 100644 --- a/simpleperf/runtest/function_pthread.cpp +++ b/simpleperf/runtest/function_pthread.cpp @@ -17,17 +17,19 @@ void MainThreadFunction() { } int main() { - pthread_t thread; - int ret = pthread_create(&thread, nullptr, ChildThreadFunction, nullptr); - if (ret != 0) { - fprintf(stderr, "pthread_create failed: %s\n", strerror(ret)); - exit(1); - } - MainThreadFunction(); - ret = pthread_join(thread, nullptr); - if (ret != 0) { - fprintf(stderr, "pthread_join failed: %s\n", strerror(ret)); - exit(1); + while (true) { + pthread_t thread; + int ret = pthread_create(&thread, nullptr, ChildThreadFunction, nullptr); + if (ret != 0) { + fprintf(stderr, "pthread_create failed: %s\n", strerror(ret)); + exit(1); + } + MainThreadFunction(); + ret = pthread_join(thread, nullptr); + if (ret != 0) { + fprintf(stderr, "pthread_join failed: %s\n", strerror(ret)); + exit(1); + } } return 0; } diff --git a/simpleperf/runtest/function_recursive.cpp b/simpleperf/runtest/function_recursive.cpp index d8d28bcc..bf60668b 100644 --- a/simpleperf/runtest/function_recursive.cpp +++ b/simpleperf/runtest/function_recursive.cpp @@ -11,6 +11,8 @@ void FunctionRecursive(int loop) { } int main() { - FunctionRecursive(10); + while (true) { + FunctionRecursive(10); + } return 0; } diff --git a/simpleperf/runtest/one_function.cpp b/simpleperf/runtest/one_function.cpp index 49090aca..561bb5a5 100644 --- a/simpleperf/runtest/one_function.cpp +++ b/simpleperf/runtest/one_function.cpp @@ -6,6 +6,8 @@ void Function1() { } int main() { - Function1(); + while (true) { + Function1(); + } return 0; } diff --git a/simpleperf/runtest/runtest.py b/simpleperf/runtest/runtest.py index bbfdc48a..77fc5669 100644 --- a/simpleperf/runtest/runtest.py +++ b/simpleperf/runtest/runtest.py @@ -277,22 +277,29 @@ def load_symbol_relation_requirement(symbol_item): class Runner(object): - def __init__(self, perf_path): + def __init__(self, target, perf_path): + self.target = target self.perf_path = perf_path + self.use_callgraph = False + self.sampler = 'cpu-cycles' def record(self, test_executable_name, record_file, additional_options=[]): - call_args = [self.perf_path, - 'record'] + additional_options + ['-e', - 'cpu-cycles:u', - '-o', - record_file, - test_executable_name] + call_args = [self.perf_path, 'record'] + call_args += ['--duration', '1'] + call_args += ['-e', '%s:u' % self.sampler] + if self.use_callgraph: + call_args += ['-f', '1000', '-g'] + call_args += ['-o', record_file] + call_args += additional_options + call_args += [test_executable_name] self._call(call_args) def report(self, record_file, report_file, additional_options=[]): - call_args = [self.perf_path, - 'report'] + additional_options + ['-i', - record_file] + call_args = [self.perf_path, 'report'] + call_args += ['-i', record_file] + if self.use_callgraph: + call_args += ['-g', 'callee'] + call_args += additional_options self._call(call_args, report_file) def _call(self, args, output_file=None): @@ -303,6 +310,9 @@ class HostRunner(Runner): """Run perf test on host.""" + def __init__(self, perf_path): + super(HostRunner, self).__init__('host', perf_path) + def _call(self, args, output_file=None): output_fh = None if output_file is not None: @@ -318,8 +328,8 @@ class DeviceRunner(Runner): def __init__(self, perf_path): self.tmpdir = '/data/local/tmp/' + super(DeviceRunner, self).__init__('device', self.tmpdir + perf_path) self._download(os.environ['OUT'] + '/system/xbin/' + perf_path, self.tmpdir) - self.perf_path = self.tmpdir + perf_path def _call(self, args, output_file=None): output_fh = None @@ -518,7 +528,7 @@ class ReportAnalyzer(object): return result -def runtest(host, device, normal, callgraph, selected_tests): +def runtest(host, device, normal, callgraph, use_inplace_sampler, selected_tests): tests = load_config_file(os.path.dirname(os.path.realpath(__file__)) + \ '/runtest.conf') host_runner = HostRunner('simpleperf') @@ -581,26 +591,76 @@ def runtest(host, device, normal, callgraph, selected_tests): if not result: exit(1) + +def build_runner(target, use_callgraph, sampler): + if target == 'host': + runner = HostRunner('simpleperf') + else: + runner = DeviceRunner('simpleperf') + runner.use_callgraph = use_callgraph + runner.sampler = sampler + return runner + + +def test_with_runner(runner, tests): + report_analyzer = ReportAnalyzer() + for test in tests: + runner.record(test.executable_name, 'perf.data') + if runner.sampler == 'inplace-sampler': + # TODO: fix this when inplace-sampler actually works. + runner.report('perf.data', 'perf.report') + symbols = report_analyzer._read_report_file('perf.report', runner.use_callgraph) + result = False + if len(symbols) == 1 and symbols[0].name == 'fake_elf[+0]': + result = True + else: + runner.report('perf.data', 'perf.report', additional_options = test.report_options) + result = report_analyzer.check_report_file(test, 'perf.report', runner.use_callgraph) + str = 'test %s on %s ' % (test.test_name, runner.target) + if runner.use_callgraph: + str += 'with call graph ' + str += 'using %s ' % runner.sampler + str += ' Succeeded' if result else 'Failed' + print str + if not result: + exit(1) + + +def runtest(target_options, use_callgraph_options, sampler_options, selected_tests): + tests = load_config_file(os.path.dirname(os.path.realpath(__file__)) + \ + '/runtest.conf') + if selected_tests is not None: + new_tests = [] + for test in tests: + if test.test_name in selected_tests: + new_tests.append(test) + tests = new_tests + for target in target_options: + for use_callgraph in use_callgraph_options: + for sampler in sampler_options: + runner = build_runner(target, use_callgraph, sampler) + test_with_runner(runner, tests) + + def main(): - host = True - device = True - normal = True - callgraph = True + target_options = ['host', 'target'] + use_callgraph_options = [False, True] + sampler_options = ['cpu-cycles', 'inplace-sampler'] selected_tests = None i = 1 while i < len(sys.argv): if sys.argv[i] == '--host': - host = True - device = False + use_callgraph_options = ['host'] elif sys.argv[i] == '--device': - host = False - device = True + use_callgraph_options = ['device'] elif sys.argv[i] == '--normal': - normal = True - callgraph = False + use_callgraph_options = [False] elif sys.argv[i] == '--callgraph': - normal = False - callgraph = True + use_callgraph_options = [True] + elif sys.argv[i] == '--no-inplace-sampler': + sampler_options = ['cpu-cycles'] + elif sys.argv[i] == '--inplace-sampler': + sampler_options = ['inplace-sampler'] elif sys.argv[i] == '--test': if i < len(sys.argv): i += 1 @@ -609,7 +669,7 @@ def main(): selected_tests = {} selected_tests[test] = True i += 1 - runtest(host, device, normal, callgraph, selected_tests) + runtest(target_options, use_callgraph_options, sampler_options, selected_tests) if __name__ == '__main__': main() diff --git a/simpleperf/runtest/two_functions.cpp b/simpleperf/runtest/two_functions.cpp index 1d3e3893..b74c1538 100644 --- a/simpleperf/runtest/two_functions.cpp +++ b/simpleperf/runtest/two_functions.cpp @@ -18,7 +18,9 @@ void Function2() { } int main() { - Function1(); - Function2(); + while (true) { + Function1(); + Function2(); + } return 0; } |