162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Refactored from builtin-top.c, see that files for further copyright notes.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "event.h"
962306a36Sopenharmony_ci#include "evlist.h"
1062306a36Sopenharmony_ci#include "evsel.h"
1162306a36Sopenharmony_ci#include "parse-events.h"
1262306a36Sopenharmony_ci#include "symbol.h"
1362306a36Sopenharmony_ci#include "top.h"
1462306a36Sopenharmony_ci#include "util.h"
1562306a36Sopenharmony_ci#include <inttypes.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define SNPRINTF(buf, size, fmt, args...) \
1862306a36Sopenharmony_ci({ \
1962306a36Sopenharmony_ci	size_t r = snprintf(buf, size, fmt, ## args); \
2062306a36Sopenharmony_ci	r > size ?  size : r; \
2162306a36Sopenharmony_ci})
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cisize_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	float samples_per_sec;
2662306a36Sopenharmony_ci	float ksamples_per_sec;
2762306a36Sopenharmony_ci	float esamples_percent;
2862306a36Sopenharmony_ci	struct record_opts *opts = &top->record_opts;
2962306a36Sopenharmony_ci	struct target *target = &opts->target;
3062306a36Sopenharmony_ci	size_t ret = 0;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	if (top->samples) {
3362306a36Sopenharmony_ci		samples_per_sec = top->samples / top->delay_secs;
3462306a36Sopenharmony_ci		ksamples_per_sec = top->kernel_samples / top->delay_secs;
3562306a36Sopenharmony_ci		esamples_percent = (100.0 * top->exact_samples) / top->samples;
3662306a36Sopenharmony_ci	} else {
3762306a36Sopenharmony_ci		samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
3862306a36Sopenharmony_ci	}
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	if (!perf_guest) {
4162306a36Sopenharmony_ci		float ksamples_percent = 0.0;
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci		if (samples_per_sec)
4462306a36Sopenharmony_ci			ksamples_percent = (100.0 * ksamples_per_sec) /
4562306a36Sopenharmony_ci							samples_per_sec;
4662306a36Sopenharmony_ci		ret = SNPRINTF(bf, size,
4762306a36Sopenharmony_ci			       "   PerfTop:%8.0f irqs/sec  kernel:%4.1f%%"
4862306a36Sopenharmony_ci			       "  exact: %4.1f%% lost: %" PRIu64 "/%" PRIu64 " drop: %" PRIu64 "/%" PRIu64 " [",
4962306a36Sopenharmony_ci			       samples_per_sec, ksamples_percent, esamples_percent,
5062306a36Sopenharmony_ci			       top->lost, top->lost_total, top->drop, top->drop_total);
5162306a36Sopenharmony_ci	} else {
5262306a36Sopenharmony_ci		float us_samples_per_sec = top->us_samples / top->delay_secs;
5362306a36Sopenharmony_ci		float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
5462306a36Sopenharmony_ci		float guest_us_samples_per_sec = top->guest_us_samples / top->delay_secs;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci		ret = SNPRINTF(bf, size,
5762306a36Sopenharmony_ci			       "   PerfTop:%8.0f irqs/sec  kernel:%4.1f%% us:%4.1f%%"
5862306a36Sopenharmony_ci			       " guest kernel:%4.1f%% guest us:%4.1f%%"
5962306a36Sopenharmony_ci			       " exact: %4.1f%% [", samples_per_sec,
6062306a36Sopenharmony_ci			       100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
6162306a36Sopenharmony_ci						 samples_per_sec)),
6262306a36Sopenharmony_ci			       100.0 - (100.0 * ((samples_per_sec - us_samples_per_sec) /
6362306a36Sopenharmony_ci						 samples_per_sec)),
6462306a36Sopenharmony_ci			       100.0 - (100.0 * ((samples_per_sec -
6562306a36Sopenharmony_ci						  guest_kernel_samples_per_sec) /
6662306a36Sopenharmony_ci						 samples_per_sec)),
6762306a36Sopenharmony_ci			       100.0 - (100.0 * ((samples_per_sec -
6862306a36Sopenharmony_ci						  guest_us_samples_per_sec) /
6962306a36Sopenharmony_ci						 samples_per_sec)),
7062306a36Sopenharmony_ci			       esamples_percent);
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	if (top->evlist->core.nr_entries == 1) {
7462306a36Sopenharmony_ci		struct evsel *first = evlist__first(top->evlist);
7562306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, "%" PRIu64 "%s ",
7662306a36Sopenharmony_ci				(uint64_t)first->core.attr.sample_period,
7762306a36Sopenharmony_ci				opts->freq ? "Hz" : "");
7862306a36Sopenharmony_ci	}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	ret += SNPRINTF(bf + ret, size - ret, "%s", evsel__name(top->sym_evsel));
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	ret += SNPRINTF(bf + ret, size - ret, "], ");
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	if (target->pid)
8562306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s",
8662306a36Sopenharmony_ci				target->pid);
8762306a36Sopenharmony_ci	else if (target->tid)
8862306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s",
8962306a36Sopenharmony_ci				target->tid);
9062306a36Sopenharmony_ci	else if (target->uid_str != NULL)
9162306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, " (uid: %s",
9262306a36Sopenharmony_ci				target->uid_str);
9362306a36Sopenharmony_ci	else
9462306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, " (all");
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	if (target->cpu_list)
9762306a36Sopenharmony_ci		ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)",
9862306a36Sopenharmony_ci				perf_cpu_map__nr(top->evlist->core.user_requested_cpus) > 1
9962306a36Sopenharmony_ci				? "s" : "",
10062306a36Sopenharmony_ci				target->cpu_list);
10162306a36Sopenharmony_ci	else {
10262306a36Sopenharmony_ci		if (target->tid)
10362306a36Sopenharmony_ci			ret += SNPRINTF(bf + ret, size - ret, ")");
10462306a36Sopenharmony_ci		else
10562306a36Sopenharmony_ci			ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)",
10662306a36Sopenharmony_ci					perf_cpu_map__nr(top->evlist->core.user_requested_cpus),
10762306a36Sopenharmony_ci					perf_cpu_map__nr(top->evlist->core.user_requested_cpus) > 1
10862306a36Sopenharmony_ci					? "s" : "");
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	perf_top__reset_sample_counters(top);
11262306a36Sopenharmony_ci	return ret;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_civoid perf_top__reset_sample_counters(struct perf_top *top)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	top->samples = top->us_samples = top->kernel_samples =
11862306a36Sopenharmony_ci	top->exact_samples = top->guest_kernel_samples =
11962306a36Sopenharmony_ci	top->guest_us_samples = top->lost = top->drop = 0;
12062306a36Sopenharmony_ci}
121