xref: /openbmc/linux/tools/perf/bench/synthesize.c (revision c6fddb28)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Benchmark synthesis of perf events such as at the start of a 'perf
4  * record'. Synthesis is done on the current process and the 'dummy' event
5  * handlers are invoked that support dump_trace but otherwise do nothing.
6  *
7  * Copyright 2019 Google LLC.
8  */
9 #include <stdio.h>
10 #include "bench.h"
11 #include "../util/debug.h"
12 #include "../util/session.h"
13 #include "../util/synthetic-events.h"
14 #include "../util/target.h"
15 #include "../util/thread_map.h"
16 #include "../util/tool.h"
17 #include <linux/err.h>
18 #include <linux/time64.h>
19 #include <subcmd/parse-options.h>
20 
21 static unsigned int iterations = 10000;
22 
23 static const struct option options[] = {
24 	OPT_UINTEGER('i', "iterations", &iterations,
25 		"Number of iterations used to compute average"),
26 	OPT_END()
27 };
28 
29 static const char *const usage[] = {
30 	"perf bench internals synthesize <options>",
31 	NULL
32 };
33 
34 
35 static int do_synthesize(struct perf_session *session,
36 			struct perf_thread_map *threads,
37 			struct target *target, bool data_mmap)
38 {
39 	const unsigned int nr_threads_synthesize = 1;
40 	struct timeval start, end, diff;
41 	u64 runtime_us;
42 	unsigned int i;
43 	double average;
44 	int err;
45 
46 	gettimeofday(&start, NULL);
47 	for (i = 0; i < iterations; i++) {
48 		err = machine__synthesize_threads(&session->machines.host,
49 						target, threads, data_mmap,
50 						nr_threads_synthesize);
51 		if (err)
52 			return err;
53 	}
54 
55 	gettimeofday(&end, NULL);
56 	timersub(&end, &start, &diff);
57 	runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
58 	average = (double)runtime_us/(double)iterations;
59 	printf("Average %ssynthesis took: %f usec\n",
60 		data_mmap ? "data " : "", average);
61 	return 0;
62 }
63 
64 int bench_synthesize(int argc, const char **argv)
65 {
66 	struct perf_tool tool;
67 	struct perf_session *session;
68 	struct target target = {
69 		.pid = "self",
70 	};
71 	struct perf_thread_map *threads;
72 	int err;
73 
74 	argc = parse_options(argc, argv, options, usage, 0);
75 
76 	session = perf_session__new(NULL, false, NULL);
77 	if (IS_ERR(session)) {
78 		pr_err("Session creation failed.\n");
79 		return PTR_ERR(session);
80 	}
81 	threads = thread_map__new_by_pid(getpid());
82 	if (!threads) {
83 		pr_err("Thread map creation failed.\n");
84 		err = -ENOMEM;
85 		goto err_out;
86 	}
87 	perf_tool__fill_defaults(&tool);
88 
89 	err = do_synthesize(session, threads, &target, false);
90 	if (err)
91 		goto err_out;
92 
93 	err = do_synthesize(session, threads, &target, true);
94 
95 err_out:
96 	if (threads)
97 		perf_thread_map__put(threads);
98 
99 	perf_session__delete(session);
100 	return err;
101 }
102