Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 350054
b: refs/heads/master
c: 341487a
h: refs/heads/master
v: v3
  • Loading branch information
Feng Tang authored and Arnaldo Carvalho de Melo committed Feb 6, 2013
1 parent 307e9dd commit a530c65
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0fbdad078a70ed72248c3d30fe32e45e83be00d1
refs/heads/master: 341487ab561f3937a5283dd77c5660b1ee3b1f9e
112 changes: 111 additions & 1 deletion trunk/tools/perf/ui/browsers/hists.c
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,96 @@ static inline bool is_report_browser(void *timer)
return timer == NULL;
}

/*
* Only runtime switching of perf data file will make "input_name" point
* to a malloced buffer. So add "is_input_name_malloced" flag to decide
* whether we need to call free() for current "input_name" during the switch.
*/
static bool is_input_name_malloced = false;

static int switch_data_file(void)
{
char *pwd, *options[32], *abs_path[32], *tmp;
DIR *pwd_dir;
int nr_options = 0, choice = -1, ret = -1;
struct dirent *dent;

pwd = getenv("PWD");
if (!pwd)
return ret;

pwd_dir = opendir(pwd);
if (!pwd_dir)
return ret;

memset(options, 0, sizeof(options));
memset(options, 0, sizeof(abs_path));

while ((dent = readdir(pwd_dir))) {
char path[PATH_MAX];
u64 magic;
char *name = dent->d_name;
FILE *file;

if (!(dent->d_type == DT_REG))
continue;

snprintf(path, sizeof(path), "%s/%s", pwd, name);

file = fopen(path, "r");
if (!file)
continue;

if (fread(&magic, 1, 8, file) < 8)
goto close_file_and_continue;

if (is_perf_magic(magic)) {
options[nr_options] = strdup(name);
if (!options[nr_options])
goto close_file_and_continue;

abs_path[nr_options] = strdup(path);
if (!abs_path[nr_options]) {
free(options[nr_options]);
ui__warning("Can't search all data files due to memory shortage.\n");
fclose(file);
break;
}

nr_options++;
}

close_file_and_continue:
fclose(file);
if (nr_options >= 32) {
ui__warning("Too many perf data files in PWD!\n"
"Only the first 32 files will be listed.\n");
break;
}
}
closedir(pwd_dir);

if (nr_options) {
choice = ui__popup_menu(nr_options, options);
if (choice < nr_options && choice >= 0) {
tmp = strdup(abs_path[choice]);
if (tmp) {
if (is_input_name_malloced)
free((void *)input_name);
input_name = tmp;
is_input_name_malloced = true;
ret = 0;
} else
ui__warning("Data switch failed due to memory shortage!\n");
}
}

free_popup_options(options, nr_options);
free_popup_options(abs_path, nr_options);
return ret;
}


static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name,
bool left_exits,
Expand Down Expand Up @@ -1275,7 +1365,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
int choice = 0,
annotate = -2, zoom_dso = -2, zoom_thread = -2,
annotate_f = -2, annotate_t = -2, browse_map = -2;
int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2;
int scripts_comm = -2, scripts_symbol = -2,
scripts_all = -2, switch_data = -2;

nr_options = 0;

Expand Down Expand Up @@ -1332,6 +1423,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (is_report_browser(hbt))
goto do_scripts;
continue;
case 's':
if (is_report_browser(hbt))
goto do_data_switch;
continue;
case K_F1:
case 'h':
case '?':
Expand All @@ -1351,6 +1446,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
"d Zoom into current DSO\n"
"t Zoom into current Thread\n"
"r Run available scripts('perf report' only)\n"
"s Switch to another data file in PWD ('perf report' only)\n"
"P Print histograms to perf.hist.N\n"
"V Verbose (DSO names in callchains, etc)\n"
"/ Filter symbol by name");
Expand Down Expand Up @@ -1458,6 +1554,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (asprintf(&options[nr_options], "Run scripts for all samples") > 0)
scripts_all = nr_options++;

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

script_browse(script_opt);
}
/* Switch to another data file */
else if (choice == switch_data) {
do_data_switch:
if (!switch_data_file()) {
key = K_SWITCH_INPUT_DATA;
break;
} else
ui__warning("Won't switch the data files due to\n"
"no valid data file get selected!\n");
}
}
out_free_stack:
pstack__delete(fstack);
Expand Down Expand Up @@ -1694,6 +1803,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
"Do you really want to exit?"))
continue;
/* Fall thru */
case K_SWITCH_INPUT_DATA:
case 'q':
case CTRL('c'):
goto out;
Expand Down
1 change: 1 addition & 0 deletions trunk/tools/perf/ui/keysyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
#define K_TIMER -1
#define K_ERROR -2
#define K_RESIZE -3
#define K_SWITCH_INPUT_DATA -4

#endif /* _PERF_KEYSYMS_H_ */

0 comments on commit a530c65

Please sign in to comment.