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