Messages in this thread Patch in this message | | | From | Namhyung Kim <> | Subject | [PATCH 38/40] perf session: Handle index files generally | Date | Mon, 18 May 2015 09:30:53 +0900 |
| |
The current code assumes that the number of index item and cpu are matched so it creates that number of threads. But it's not the case of non-system-wide session or data came from different machine.
Just creates threads at most number of online cpus and process data.
Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/perf/util/session.c | 79 ++++++++++++++++++++++++++++++++++------------- tools/perf/util/tool.h | 1 - 2 files changed, 58 insertions(+), 22 deletions(-)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index dcb9747bbb49..5f6c319bd236 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1679,25 +1679,50 @@ static struct ui_progress_ops mt_progress__ops = { .update = mt_progress__update, }; +static int perf_session__get_index(struct perf_session *session) +{ + int ret; + static unsigned idx = 1; + static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER; + + pthread_mutex_lock(&idx_lock); + if (idx < session->header.nr_index) + ret = idx++; + else + ret = -1; + pthread_mutex_unlock(&idx_lock); + + return ret; +} + static void *processing_thread_idx(void *arg) { struct perf_tool_mt *mt_tool = arg; struct perf_session *session = mt_tool->session; - u64 offset = session->header.index[mt_tool->idx].offset; - u64 size = session->header.index[mt_tool->idx].size; u64 file_size = perf_data_file__size(session->file); + int idx; - ui_progress__init(&mt_tool->prog, size, ""); + while ((idx = perf_session__get_index(session)) >= 0) { + u64 offset = session->header.index[idx].offset; + u64 size = session->header.index[idx].size; + struct perf_tool_mt *mtt = &mt_tool[idx]; - pr_debug("processing samples using thread [%d]\n", mt_tool->idx); - if (__perf_session__process_events(session, &mt_tool->stats, - offset, size, file_size, - &mt_tool->prog) < 0) { - pr_err("processing samples failed (thread [%d])\n", mt_tool->idx); - return NULL; + if (size == 0) + continue; + + pr_debug("processing samples [index %d]\n", idx); + + ui_progress__init(&mtt->prog, size, ""); + + if (__perf_session__process_events(mtt->session, &mtt->stats, + offset, size, file_size, + &mtt->prog) < 0) { + pr_err("processing samples failed [index %d]\n", idx); + return NULL; + } + pr_debug("processing samples done [index %d]\n", idx); } - pr_debug("processing samples done for thread [%d]\n", mt_tool->idx); return arg; } @@ -1717,6 +1742,7 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) int err, i, k; int nr_index = session->header.nr_index; u64 size = perf_data_file__size(file); + int nr_thread = sysconf(_SC_NPROCESSORS_ONLN); if (perf_data_file__is_pipe(file) || !session->header.index) { pr_err("data file doesn't contain the index table\n"); @@ -1753,15 +1779,18 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) tool->ordered_events = false; - for (i = 1; i < nr_index; i++) { + for (i = 0; i < nr_index; i++) { ms = &mt_sessions[i]; mt = &mt_tools[i]; + ms->tool = &mt->tool; ms->file = session->file; ms->evlist = session->evlist; ms->header = session->header; ms->tevent = session->tevent; + ms->machines = session->machines; + ordered_events__init(&ms->ordered_events, NULL); memcpy(&mt->tool, tool, sizeof(*tool)); mt->hists = calloc(evlist->nr_entries, sizeof(*mt->hists)); @@ -1772,20 +1801,28 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) __hists__init(&mt->hists[k]); mt->session = ms; - mt->idx = i; mt->priv = arg; mt->global_prog = &prog; - - pthread_create(&th_id[i], NULL, processing_thread_idx, mt); } - for (i = 1; i < nr_index; i++) { + if (nr_thread > nr_index - 1) + nr_thread = nr_index - 1; + + th_id = calloc(nr_thread, sizeof(*th_id)); + if (th_id == NULL) + goto out; + + for (i = 0; i < nr_thread; i++) + pthread_create(&th_id[i], NULL, processing_thread_idx, mt_tools); + + for (i = 0; i < nr_thread; i++) { pthread_join(th_id[i], (void **)&mt); - if (mt == NULL) { + if (mt == NULL) err = -EINVAL; - continue; - } + } + for (i = 0; i < nr_index; i++) { + mt = &mt_tools[i]; events_stats__add(&evlist->stats, &mt->stats); evlist__for_each(evlist, evsel) { @@ -1801,7 +1838,7 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) ui_progress__ops = orig_progress__ops; ui_progress__init(&prog, nr_entries, "Merging related events..."); - for (i = 1; i < nr_index; i++) { + for (i = 0; i < nr_index; i++) { mt = &mt_tools[i]; evlist__for_each(evlist, evsel) { @@ -1829,7 +1866,7 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) perf_session__warn_about_errors(session, &evlist->stats); if (mt_tools) { - for (i = 1; i < nr_index; i++) + for (i = 0; i < nr_index; i++) free(mt_tools[i].hists); free(mt_tools); } @@ -1839,7 +1876,7 @@ int perf_session__process_events_mt(struct perf_session *session, void *arg) return err; err: - while (i-- > 1) { + while (i-- > 0) { pthread_cancel(th_id[i]); pthread_join(th_id[i], NULL); } diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 144a414b1d5b..c96e805b9ff4 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -69,7 +69,6 @@ struct perf_tool_mt { struct perf_session *session; struct ui_progress prog; struct ui_progress *global_prog; - int idx; void *priv; }; -- 2.4.0
| |