linux/tools/perf/ui/browsers/res_sample.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Display a menu with individual samples to browse with perf script */
   3#include "hist.h"
   4#include "evsel.h"
   5#include "hists.h"
   6#include "sort.h"
   7#include "config.h"
   8#include "time-utils.h"
   9#include "../util.h"
  10#include "../../util/util.h" // perf_exe()
  11#include "../../perf.h"
  12#include <stdlib.h>
  13#include <string.h>
  14#include <linux/time64.h>
  15#include <linux/zalloc.h>
  16
  17static u64 context_len = 10 * NSEC_PER_MSEC;
  18
  19static int res_sample_config(const char *var, const char *value, void *data __maybe_unused)
  20{
  21        if (!strcmp(var, "samples.context"))
  22                return perf_config_u64(&context_len, var, value);
  23        return 0;
  24}
  25
  26void res_sample_init(void)
  27{
  28        perf_config(res_sample_config, NULL);
  29}
  30
  31int res_sample_browse(struct res_sample *res_samples, int num_res,
  32                      struct evsel *evsel, enum rstype rstype)
  33{
  34        char **names;
  35        int i, n;
  36        int choice;
  37        char *cmd;
  38        char pbuf[256], tidbuf[32], cpubuf[32];
  39        const char *perf = perf_exe(pbuf, sizeof pbuf);
  40        char trange[128], tsample[64];
  41        struct res_sample *r;
  42        char extra_format[256];
  43
  44        names = calloc(num_res, sizeof(char *));
  45        if (!names)
  46                return -1;
  47        for (i = 0; i < num_res; i++) {
  48                char tbuf[64];
  49
  50                timestamp__scnprintf_nsec(res_samples[i].time, tbuf, sizeof tbuf);
  51                if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf,
  52                             res_samples[i].cpu, res_samples[i].tid) < 0) {
  53                        while (--i >= 0)
  54                                zfree(&names[i]);
  55                        free(names);
  56                        return -1;
  57                }
  58        }
  59        choice = ui__popup_menu(num_res, names, NULL);
  60        for (i = 0; i < num_res; i++)
  61                zfree(&names[i]);
  62        free(names);
  63
  64        if (choice < 0 || choice >= num_res)
  65                return -1;
  66        r = &res_samples[choice];
  67
  68        n = timestamp__scnprintf_nsec(r->time - context_len, trange, sizeof trange);
  69        trange[n++] = ',';
  70        timestamp__scnprintf_nsec(r->time + context_len, trange + n, sizeof trange - n);
  71
  72        timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample);
  73
  74        attr_to_script(extra_format, &evsel->core.attr);
  75
  76        if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s",
  77                     perf,
  78                     input_name ? "-i " : "",
  79                     input_name ? input_name : "",
  80                     trange,
  81                     r->cpu >= 0 ? "--cpu " : "",
  82                     r->cpu >= 0 ? (sprintf(cpubuf, "%d", r->cpu), cpubuf) : "",
  83                     r->tid ? "--tid " : "",
  84                     r->tid ? (sprintf(tidbuf, "%d", r->tid), tidbuf) : "",
  85                     extra_format,
  86                     rstype == A_ASM ? "-F +insn --xed" :
  87                     rstype == A_SOURCE ? "-F +srcline,+srccode" : "",
  88                     symbol_conf.inline_name ? "--inline" : "",
  89                     "--show-lost-events ",
  90                     r->tid ? "--show-switch-events --show-task-events " : "",
  91                     tsample) < 0)
  92                return -1;
  93        run_script(cmd);
  94        free(cmd);
  95        return 0;
  96}
  97