Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Display a menu with individual samples to browse with perf script */
0003 #include "hist.h"
0004 #include "evsel.h"
0005 #include "hists.h"
0006 #include "sort.h"
0007 #include "config.h"
0008 #include "time-utils.h"
0009 #include "../util.h"
0010 #include "../../util/util.h" // perf_exe()
0011 #include "../../perf.h"
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <linux/time64.h>
0015 #include <linux/zalloc.h>
0016 
0017 static u64 context_len = 10 * NSEC_PER_MSEC;
0018 
0019 static int res_sample_config(const char *var, const char *value, void *data __maybe_unused)
0020 {
0021     if (!strcmp(var, "samples.context"))
0022         return perf_config_u64(&context_len, var, value);
0023     return 0;
0024 }
0025 
0026 void res_sample_init(void)
0027 {
0028     perf_config(res_sample_config, NULL);
0029 }
0030 
0031 int res_sample_browse(struct res_sample *res_samples, int num_res,
0032               struct evsel *evsel, enum rstype rstype)
0033 {
0034     char **names;
0035     int i, n;
0036     int choice;
0037     char *cmd;
0038     char pbuf[256], tidbuf[32], cpubuf[32];
0039     const char *perf = perf_exe(pbuf, sizeof pbuf);
0040     char trange[128], tsample[64];
0041     struct res_sample *r;
0042     char extra_format[256];
0043 
0044     names = calloc(num_res, sizeof(char *));
0045     if (!names)
0046         return -1;
0047     for (i = 0; i < num_res; i++) {
0048         char tbuf[64];
0049 
0050         timestamp__scnprintf_nsec(res_samples[i].time, tbuf, sizeof tbuf);
0051         if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf,
0052                  res_samples[i].cpu, res_samples[i].tid) < 0) {
0053             while (--i >= 0)
0054                 zfree(&names[i]);
0055             free(names);
0056             return -1;
0057         }
0058     }
0059     choice = ui__popup_menu(num_res, names, NULL);
0060     for (i = 0; i < num_res; i++)
0061         zfree(&names[i]);
0062     free(names);
0063 
0064     if (choice < 0 || choice >= num_res)
0065         return -1;
0066     r = &res_samples[choice];
0067 
0068     n = timestamp__scnprintf_nsec(r->time - context_len, trange, sizeof trange);
0069     trange[n++] = ',';
0070     timestamp__scnprintf_nsec(r->time + context_len, trange + n, sizeof trange - n);
0071 
0072     timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample);
0073 
0074     attr_to_script(extra_format, &evsel->core.attr);
0075 
0076     if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s",
0077              perf,
0078              input_name ? "-i " : "",
0079              input_name ? input_name : "",
0080              trange,
0081              r->cpu >= 0 ? "--cpu " : "",
0082              r->cpu >= 0 ? (sprintf(cpubuf, "%d", r->cpu), cpubuf) : "",
0083              r->tid ? "--tid " : "",
0084              r->tid ? (sprintf(tidbuf, "%d", r->tid), tidbuf) : "",
0085              extra_format,
0086              rstype == A_ASM ? "-F +insn --xed" :
0087              rstype == A_SOURCE ? "-F +srcline,+srccode" : "",
0088              symbol_conf.inline_name ? "--inline" : "",
0089              "--show-lost-events ",
0090              r->tid ? "--show-switch-events --show-task-events " : "",
0091              tsample) < 0)
0092         return -1;
0093     run_script(cmd);
0094     free(cmd);
0095     return 0;
0096 }