diff options
Diffstat (limited to 'tools/perf/builtin-sched.c')
-rw-r--r-- | tools/perf/builtin-sched.c | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index cc4ba506e119..9ab300b6f131 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -193,8 +193,8 @@ struct perf_sched { * weird events, such as a task being switched away that is not current. */ struct perf_cpu max_cpu; - u32 curr_pid[MAX_CPUS]; - struct thread *curr_thread[MAX_CPUS]; + u32 *curr_pid; + struct thread **curr_thread; char next_shortname1; char next_shortname2; unsigned int replay_repeat; @@ -224,7 +224,7 @@ struct perf_sched { u64 run_avg; u64 all_runtime; u64 all_count; - u64 cpu_last_switched[MAX_CPUS]; + u64 *cpu_last_switched; struct rb_root_cached atom_root, sorted_atom_root, merged_atom_root; struct list_head sort_list, cmp_pid; bool force; @@ -916,12 +916,12 @@ static int replay_fork_event(struct perf_sched *sched, if (verbose > 0) { printf("fork event\n"); - printf("... parent: %s/%d\n", thread__comm_str(parent), parent->tid); - printf("... child: %s/%d\n", thread__comm_str(child), child->tid); + printf("... parent: %s/%d\n", thread__comm_str(parent), thread__tid(parent)); + printf("... child: %s/%d\n", thread__comm_str(child), thread__tid(child)); } - register_pid(sched, parent->tid, thread__comm_str(parent)); - register_pid(sched, child->tid, thread__comm_str(child)); + register_pid(sched, thread__tid(parent), thread__comm_str(parent)); + register_pid(sched, thread__tid(child), thread__comm_str(child)); out_put: thread__put(child); thread__put(parent); @@ -1316,7 +1316,7 @@ static int latency_migrate_task_event(struct perf_sched *sched, if (!atoms) { if (thread_atoms_insert(sched, migrant)) goto out_put; - register_pid(sched, migrant->tid, thread__comm_str(migrant)); + register_pid(sched, thread__tid(migrant), thread__comm_str(migrant)); atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid); if (!atoms) { pr_err("migration-event: Internal tree error"); @@ -1359,10 +1359,13 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_ sched->all_runtime += work_list->total_runtime; sched->all_count += work_list->nb_atoms; - if (work_list->num_merged > 1) - ret = printf(" %s:(%d) ", thread__comm_str(work_list->thread), work_list->num_merged); - else - ret = printf(" %s:%d ", thread__comm_str(work_list->thread), work_list->thread->tid); + if (work_list->num_merged > 1) { + ret = printf(" %s:(%d) ", thread__comm_str(work_list->thread), + work_list->num_merged); + } else { + ret = printf(" %s:%d ", thread__comm_str(work_list->thread), + thread__tid(work_list->thread)); + } for (i = 0; i < 24 - ret; i++) printf(" "); @@ -1380,13 +1383,17 @@ static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_ static int pid_cmp(struct work_atoms *l, struct work_atoms *r) { - if (l->thread == r->thread) + pid_t l_tid, r_tid; + + if (RC_CHK_ACCESS(l->thread) == RC_CHK_ACCESS(r->thread)) return 0; - if (l->thread->tid < r->thread->tid) + l_tid = thread__tid(l->thread); + r_tid = thread__tid(r->thread); + if (l_tid < r_tid) return -1; - if (l->thread->tid > r->thread->tid) + if (l_tid > r_tid) return 1; - return (int)(l->thread - r->thread); + return (int)(RC_CHK_ACCESS(l->thread) - RC_CHK_ACCESS(r->thread)); } static int avg_cmp(struct work_atoms *l, struct work_atoms *r) @@ -1679,14 +1686,14 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel, timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp)); color_fprintf(stdout, color, " %12s secs ", stimestamp); - if (new_shortname || tr->comm_changed || (verbose > 0 && sched_in->tid)) { + if (new_shortname || tr->comm_changed || (verbose > 0 && thread__tid(sched_in))) { const char *pid_color = color; if (thread__has_color(sched_in)) pid_color = COLOR_PIDS; color_fprintf(stdout, pid_color, "%s => %s:%d", - tr->shortname, thread__comm_str(sched_in), sched_in->tid); + tr->shortname, thread__comm_str(sched_in), thread__tid(sched_in)); tr->comm_changed = false; } @@ -1948,8 +1955,8 @@ static char *timehist_get_commstr(struct thread *thread) { static char str[32]; const char *comm = thread__comm_str(thread); - pid_t tid = thread->tid; - pid_t pid = thread->pid_; + pid_t tid = thread__tid(thread); + pid_t pid = thread__pid(thread); int n; if (pid == 0) @@ -2032,7 +2039,7 @@ static char task_state_char(struct thread *thread, int state) unsigned bit = state ? ffs(state) : 0; /* 'I' for idle */ - if (thread->tid == 0) + if (thread__tid(thread) == 0) return 'I'; return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?'; @@ -2067,7 +2074,7 @@ static void timehist_print_sample(struct perf_sched *sched, for (i = 0; i < max_cpus; ++i) { /* flag idle times with 'i'; others are sched events */ if (i == sample->cpu) - c = (thread->tid == 0) ? 'i' : 's'; + c = (thread__tid(thread) == 0) ? 'i' : 's'; else c = ' '; printf("%c", c); @@ -2094,7 +2101,7 @@ static void timehist_print_sample(struct perf_sched *sched, if (sched->show_wakeups && !sched->show_next) printf(" %-*s", comm_width, ""); - if (thread->tid == 0) + if (thread__tid(thread) == 0) goto out; if (sched->show_callchain) @@ -2104,7 +2111,7 @@ static void timehist_print_sample(struct perf_sched *sched, EVSEL__PRINT_SYM | EVSEL__PRINT_ONELINE | EVSEL__PRINT_CALLCHAIN_ARROW | EVSEL__PRINT_SKIP_IGNORED, - &callchain_cursor, symbol_conf.bt_stop_list, stdout); + get_tls_callchain_cursor(), symbol_conf.bt_stop_list, stdout); out: printf("\n"); @@ -2189,7 +2196,7 @@ static void save_task_callchain(struct perf_sched *sched, struct evsel *evsel, struct machine *machine) { - struct callchain_cursor *cursor = &callchain_cursor; + struct callchain_cursor *cursor; struct thread *thread; /* want main thread for process - has maps */ @@ -2202,6 +2209,8 @@ static void save_task_callchain(struct perf_sched *sched, if (!sched->show_callchain || sample->callchain == NULL) return; + cursor = get_tls_callchain_cursor(); + if (thread__resolve_callchain(thread, cursor, evsel, sample, NULL, NULL, sched->max_stack + 2) != 0) { if (verbose > 0) @@ -2331,10 +2340,16 @@ static void save_idle_callchain(struct perf_sched *sched, struct idle_thread_runtime *itr, struct perf_sample *sample) { + struct callchain_cursor *cursor; + if (!sched->show_callchain || sample->callchain == NULL) return; - callchain_cursor__copy(&itr->cursor, &callchain_cursor); + cursor = get_tls_callchain_cursor(); + if (cursor == NULL) + return; + + callchain_cursor__copy(&itr->cursor, cursor); } static struct thread *timehist_get_thread(struct perf_sched *sched, @@ -2577,6 +2592,7 @@ static int timehist_sched_change_event(struct perf_tool *tool, int rc = 0; int state = evsel__intval(evsel, sample, "prev_state"); + addr_location__init(&al); if (machine__resolve(machine, &al, sample) < 0) { pr_err("problem processing %d event. skipping it\n", event->header.type); @@ -2626,7 +2642,7 @@ static int timehist_sched_change_event(struct perf_tool *tool, t = ptime->end; } - if (!sched->idle_hist || thread->tid == 0) { + if (!sched->idle_hist || thread__tid(thread) == 0) { if (!cpu_list || test_bit(sample->cpu, cpu_bitmap)) timehist_update_runtime_stats(tr, t, tprev); @@ -2634,7 +2650,7 @@ static int timehist_sched_change_event(struct perf_tool *tool, struct idle_thread_runtime *itr = (void *)tr; struct thread_runtime *last_tr; - BUG_ON(thread->tid != 0); + BUG_ON(thread__tid(thread) != 0); if (itr->last_thread == NULL) goto out; @@ -2685,6 +2701,7 @@ out: evsel__save_time(evsel, sample->time, sample->cpu); + addr_location__exit(&al); return rc; } @@ -2719,7 +2736,7 @@ static void print_thread_runtime(struct thread *t, float stddev; printf("%*s %5d %9" PRIu64 " ", - comm_width, timehist_get_commstr(t), t->ppid, + comm_width, timehist_get_commstr(t), thread__ppid(t), (u64) r->run_stats.n); print_sched_time(r->total_run_time, 8); @@ -2739,7 +2756,7 @@ static void print_thread_waittime(struct thread *t, struct thread_runtime *r) { printf("%*s %5d %9" PRIu64 " ", - comm_width, timehist_get_commstr(t), t->ppid, + comm_width, timehist_get_commstr(t), thread__ppid(t), (u64) r->run_stats.n); print_sched_time(r->total_run_time, 8); @@ -2760,7 +2777,7 @@ struct total_run_stats { u64 total_run_time; }; -static int __show_thread_runtime(struct thread *t, void *priv) +static int show_thread_runtime(struct thread *t, void *priv) { struct total_run_stats *stats = priv; struct thread_runtime *r; @@ -2783,22 +2800,6 @@ static int __show_thread_runtime(struct thread *t, void *priv) return 0; } -static int show_thread_runtime(struct thread *t, void *priv) -{ - if (t->dead) - return 0; - - return __show_thread_runtime(t, priv); -} - -static int show_deadthread_runtime(struct thread *t, void *priv) -{ - if (!t->dead) - return 0; - - return __show_thread_runtime(t, priv); -} - static size_t callchain__fprintf_folded(FILE *fp, struct callchain_node *node) { const char *sep = " <- "; @@ -2890,11 +2891,6 @@ static void timehist_print_summary(struct perf_sched *sched, if (!task_count) printf("<no still running tasks>\n"); - printf("\nTerminated tasks:\n"); - machine__for_each_thread(m, show_deadthread_runtime, &totals); - if (task_count == totals.task_count) - printf("<no terminated tasks>\n"); - /* CPU idle stats not tracked when samples were skipped */ if (sched->skipped_samples && !sched->idle_hist) return; @@ -3599,7 +3595,22 @@ int cmd_sched(int argc, const char **argv) mutex_init(&sched.start_work_mutex); mutex_init(&sched.work_done_wait_mutex); - for (i = 0; i < ARRAY_SIZE(sched.curr_pid); i++) + sched.curr_thread = calloc(MAX_CPUS, sizeof(*sched.curr_thread)); + if (!sched.curr_thread) { + ret = -ENOMEM; + goto out; + } + sched.cpu_last_switched = calloc(MAX_CPUS, sizeof(*sched.cpu_last_switched)); + if (!sched.cpu_last_switched) { + ret = -ENOMEM; + goto out; + } + sched.curr_pid = malloc(MAX_CPUS * sizeof(*sched.curr_pid)); + if (!sched.curr_pid) { + ret = -ENOMEM; + goto out; + } + for (i = 0; i < MAX_CPUS; i++) sched.curr_pid[i] = -1; argc = parse_options_subcommand(argc, argv, sched_options, sched_subcommands, @@ -3668,6 +3679,9 @@ int cmd_sched(int argc, const char **argv) } out: + free(sched.curr_pid); + free(sched.cpu_last_switched); + free(sched.curr_thread); mutex_destroy(&sched.start_work_mutex); mutex_destroy(&sched.work_done_wait_mutex); |