Skip to content

Commit 341487a

Browse files
ftang1acmel
authored andcommitted
perf hists browser: Add option for runtime switching perf data file
Based on perf report/top/scripts browser integration idea from acme. This will enable user to runtime switch the data file, when this option is selected, it will popup all the legal data files in current working directory, and the filename selected by user is saved in the global variable "input_name", and a new key 'K_SWITCH_INPUT_DATA' will be passed back to the built-in command which will perform the switch. This initial version only enables it for 'perf report'. v2: rebase to latest 'perf/core' branch (6e1d4dd) of acme's perf tree Signed-off-by: Feng Tang <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 0fbdad0 commit 341487a

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

tools/perf/ui/browsers/hists.c

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,96 @@ static inline bool is_report_browser(void *timer)
12411241
return timer == NULL;
12421242
}
12431243

1244+
/*
1245+
* Only runtime switching of perf data file will make "input_name" point
1246+
* to a malloced buffer. So add "is_input_name_malloced" flag to decide
1247+
* whether we need to call free() for current "input_name" during the switch.
1248+
*/
1249+
static bool is_input_name_malloced = false;
1250+
1251+
static int switch_data_file(void)
1252+
{
1253+
char *pwd, *options[32], *abs_path[32], *tmp;
1254+
DIR *pwd_dir;
1255+
int nr_options = 0, choice = -1, ret = -1;
1256+
struct dirent *dent;
1257+
1258+
pwd = getenv("PWD");
1259+
if (!pwd)
1260+
return ret;
1261+
1262+
pwd_dir = opendir(pwd);
1263+
if (!pwd_dir)
1264+
return ret;
1265+
1266+
memset(options, 0, sizeof(options));
1267+
memset(options, 0, sizeof(abs_path));
1268+
1269+
while ((dent = readdir(pwd_dir))) {
1270+
char path[PATH_MAX];
1271+
u64 magic;
1272+
char *name = dent->d_name;
1273+
FILE *file;
1274+
1275+
if (!(dent->d_type == DT_REG))
1276+
continue;
1277+
1278+
snprintf(path, sizeof(path), "%s/%s", pwd, name);
1279+
1280+
file = fopen(path, "r");
1281+
if (!file)
1282+
continue;
1283+
1284+
if (fread(&magic, 1, 8, file) < 8)
1285+
goto close_file_and_continue;
1286+
1287+
if (is_perf_magic(magic)) {
1288+
options[nr_options] = strdup(name);
1289+
if (!options[nr_options])
1290+
goto close_file_and_continue;
1291+
1292+
abs_path[nr_options] = strdup(path);
1293+
if (!abs_path[nr_options]) {
1294+
free(options[nr_options]);
1295+
ui__warning("Can't search all data files due to memory shortage.\n");
1296+
fclose(file);
1297+
break;
1298+
}
1299+
1300+
nr_options++;
1301+
}
1302+
1303+
close_file_and_continue:
1304+
fclose(file);
1305+
if (nr_options >= 32) {
1306+
ui__warning("Too many perf data files in PWD!\n"
1307+
"Only the first 32 files will be listed.\n");
1308+
break;
1309+
}
1310+
}
1311+
closedir(pwd_dir);
1312+
1313+
if (nr_options) {
1314+
choice = ui__popup_menu(nr_options, options);
1315+
if (choice < nr_options && choice >= 0) {
1316+
tmp = strdup(abs_path[choice]);
1317+
if (tmp) {
1318+
if (is_input_name_malloced)
1319+
free((void *)input_name);
1320+
input_name = tmp;
1321+
is_input_name_malloced = true;
1322+
ret = 0;
1323+
} else
1324+
ui__warning("Data switch failed due to memory shortage!\n");
1325+
}
1326+
}
1327+
1328+
free_popup_options(options, nr_options);
1329+
free_popup_options(abs_path, nr_options);
1330+
return ret;
1331+
}
1332+
1333+
12441334
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
12451335
const char *helpline, const char *ev_name,
12461336
bool left_exits,
@@ -1275,7 +1365,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
12751365
int choice = 0,
12761366
annotate = -2, zoom_dso = -2, zoom_thread = -2,
12771367
annotate_f = -2, annotate_t = -2, browse_map = -2;
1278-
int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
1368+
int scripts_comm = -2, scripts_symbol = -2,
1369+
scripts_all = -2, switch_data = -2;
12791370

12801371
nr_options = 0;
12811372

@@ -1332,6 +1423,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
13321423
if (is_report_browser(hbt))
13331424
goto do_scripts;
13341425
continue;
1426+
case 's':
1427+
if (is_report_browser(hbt))
1428+
goto do_data_switch;
1429+
continue;
13351430
case K_F1:
13361431
case 'h':
13371432
case '?':
@@ -1351,6 +1446,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
13511446
"d Zoom into current DSO\n"
13521447
"t Zoom into current Thread\n"
13531448
"r Run available scripts('perf report' only)\n"
1449+
"s Switch to another data file in PWD ('perf report' only)\n"
13541450
"P Print histograms to perf.hist.N\n"
13551451
"V Verbose (DSO names in callchains, etc)\n"
13561452
"/ Filter symbol by name");
@@ -1458,6 +1554,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
14581554
if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
14591555
scripts_all = nr_options++;
14601556

1557+
if (is_report_browser(hbt) && asprintf(&options[nr_options],
1558+
"Switch to another data file in PWD") > 0)
1559+
switch_data = nr_options++;
14611560
add_exit_option:
14621561
options[nr_options++] = (char *)"Exit";
14631562
retry_popup_menu:
@@ -1568,6 +1667,16 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
15681667

15691668
script_browse(script_opt);
15701669
}
1670+
/* Switch to another data file */
1671+
else if (choice == switch_data) {
1672+
do_data_switch:
1673+
if (!switch_data_file()) {
1674+
key = K_SWITCH_INPUT_DATA;
1675+
break;
1676+
} else
1677+
ui__warning("Won't switch the data files due to\n"
1678+
"no valid data file get selected!\n");
1679+
}
15711680
}
15721681
out_free_stack:
15731682
pstack__delete(fstack);
@@ -1694,6 +1803,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
16941803
"Do you really want to exit?"))
16951804
continue;
16961805
/* Fall thru */
1806+
case K_SWITCH_INPUT_DATA:
16971807
case 'q':
16981808
case CTRL('c'):
16991809
goto out;

tools/perf/ui/keysyms.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
#define K_TIMER -1
2424
#define K_ERROR -2
2525
#define K_RESIZE -3
26+
#define K_SWITCH_INPUT_DATA -4
2627

2728
#endif /* _PERF_KEYSYMS_H_ */

0 commit comments

Comments
 (0)