perf machine: Introduce number of threads member
[deliverable/linux.git] / tools / perf / util / machine.c
index 80b9b6a87990b29e4722a956e62814130c1290de..9d0913107dc774a22ac8502e34585d12a08bbe85 100644 (file)
@@ -32,6 +32,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
 
        machine->threads = RB_ROOT;
        pthread_rwlock_init(&machine->threads_lock, NULL);
+       machine->nr_threads = 0;
        INIT_LIST_HEAD(&machine->dead_threads);
        machine->last_match = NULL;
 
@@ -430,6 +431,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine,
                 */
                thread__get(th);
                machine->last_match = th;
+               ++machine->nr_threads;
        }
 
        return th;
@@ -681,11 +683,13 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
 
 size_t machine__fprintf(struct machine *machine, FILE *fp)
 {
-       size_t ret = 0;
+       size_t ret;
        struct rb_node *nd;
 
        pthread_rwlock_rdlock(&machine->threads_lock);
 
+       ret = fprintf(fp, "Threads: %u\n", machine->nr_threads);
+
        for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
                struct thread *pos = rb_entry(nd, struct thread, rb_node);
 
@@ -908,11 +912,11 @@ int machines__create_kernel_maps(struct machines *machines, pid_t pid)
        return machine__create_kernel_maps(machine);
 }
 
-int machine__load_kallsyms(struct machine *machine, const char *filename,
-                          enum map_type type, symbol_filter_t filter)
+int __machine__load_kallsyms(struct machine *machine, const char *filename,
+                            enum map_type type, bool no_kcore, symbol_filter_t filter)
 {
        struct map *map = machine__kernel_map(machine);
-       int ret = dso__load_kallsyms(map->dso, filename, map, filter);
+       int ret = __dso__load_kallsyms(map->dso, filename, map, no_kcore, filter);
 
        if (ret > 0) {
                dso__set_loaded(map->dso, type);
@@ -927,6 +931,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename,
        return ret;
 }
 
+int machine__load_kallsyms(struct machine *machine, const char *filename,
+                          enum map_type type, symbol_filter_t filter)
+{
+       return __machine__load_kallsyms(machine, filename, type, false, filter);
+}
+
 int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
                               symbol_filter_t filter)
 {
@@ -1413,6 +1423,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread *th,
                pthread_rwlock_wrlock(&machine->threads_lock);
        rb_erase_init(&th->rb_node, &machine->threads);
        RB_CLEAR_NODE(&th->rb_node);
+       --machine->nr_threads;
        /*
         * Move it first to the dead_threads list, then drop the reference,
         * if this is the last reference, then the thread__delete destructor
@@ -1599,6 +1610,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 }
 
 static int add_callchain_ip(struct thread *thread,
+                           struct callchain_cursor *cursor,
                            struct symbol **parent,
                            struct addr_location *root_al,
                            u8 *cpumode,
@@ -1630,7 +1642,7 @@ static int add_callchain_ip(struct thread *thread,
                                 * It seems the callchain is corrupted.
                                 * Discard all.
                                 */
-                               callchain_cursor_reset(&callchain_cursor);
+                               callchain_cursor_reset(cursor);
                                return 1;
                        }
                        return 0;
@@ -1648,13 +1660,13 @@ static int add_callchain_ip(struct thread *thread,
                        /* Treat this symbol as the root,
                           forgetting its callees. */
                        *root_al = al;
-                       callchain_cursor_reset(&callchain_cursor);
+                       callchain_cursor_reset(cursor);
                }
        }
 
        if (symbol_conf.hide_unresolved && al.sym == NULL)
                return 0;
-       return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
+       return callchain_cursor_append(cursor, al.addr, al.map, al.sym);
 }
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1724,6 +1736,7 @@ static int remove_loops(struct branch_entry *l, int nr)
  * negative error code on other errors.
  */
 static int resolve_lbr_callchain_sample(struct thread *thread,
+                                       struct callchain_cursor *cursor,
                                        struct perf_sample *sample,
                                        struct symbol **parent,
                                        struct addr_location *root_al,
@@ -1756,7 +1769,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
                 */
                int mix_chain_nr = i + 1 + lbr_nr + 1;
 
-               if (mix_chain_nr > PERF_MAX_STACK_DEPTH + PERF_MAX_BRANCH_DEPTH) {
+               if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) {
                        pr_warning("corrupted callchain. skipping...\n");
                        return 0;
                }
@@ -1778,7 +1791,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
                                        ip = lbr_stack->entries[0].to;
                        }
 
-                       err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+                       err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
                        if (err)
                                return (err < 0) ? err : 0;
                }
@@ -1789,6 +1802,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
 }
 
 static int thread__resolve_callchain_sample(struct thread *thread,
+                                           struct callchain_cursor *cursor,
                                            struct perf_evsel *evsel,
                                            struct perf_sample *sample,
                                            struct symbol **parent,
@@ -1803,10 +1817,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        int skip_idx = -1;
        int first_call = 0;
 
-       callchain_cursor_reset(&callchain_cursor);
+       callchain_cursor_reset(cursor);
 
-       if (has_branch_callstack(evsel)) {
-               err = resolve_lbr_callchain_sample(thread, sample, parent,
+       if (perf_evsel__has_branch_callstack(evsel)) {
+               err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
                                                   root_al, max_stack);
                if (err)
                        return (err < 0) ? err : 0;
@@ -1816,7 +1830,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
         * Based on DWARF debug information, some architectures skip
         * a callchain entry saved by the kernel.
         */
-       if (chain->nr < PERF_MAX_STACK_DEPTH)
+       if (chain->nr < sysctl_perf_event_max_stack)
                skip_idx = arch_skip_callchain_idx(thread, chain);
 
        /*
@@ -1863,10 +1877,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
                nr = remove_loops(be, nr);
 
                for (i = 0; i < nr; i++) {
-                       err = add_callchain_ip(thread, parent, root_al,
+                       err = add_callchain_ip(thread, cursor, parent, root_al,
                                               NULL, be[i].to);
                        if (!err)
-                               err = add_callchain_ip(thread, parent, root_al,
+                               err = add_callchain_ip(thread, cursor, parent, root_al,
                                                       NULL, be[i].from);
                        if (err == -EINVAL)
                                break;
@@ -1877,7 +1891,7 @@ static int thread__resolve_callchain_sample(struct thread *thread,
        }
 
 check_calls:
-       if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) {
+       if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) {
                pr_warning("corrupted callchain. skipping...\n");
                return 0;
        }
@@ -1896,7 +1910,7 @@ check_calls:
 #endif
                ip = chain->ips[j];
 
-               err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+               err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
 
                if (err)
                        return (err < 0) ? err : 0;
@@ -1916,13 +1930,14 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
 }
 
 int thread__resolve_callchain(struct thread *thread,
+                             struct callchain_cursor *cursor,
                              struct perf_evsel *evsel,
                              struct perf_sample *sample,
                              struct symbol **parent,
                              struct addr_location *root_al,
                              int max_stack)
 {
-       int ret = thread__resolve_callchain_sample(thread, evsel,
+       int ret = thread__resolve_callchain_sample(thread, cursor, evsel,
                                                   sample, parent,
                                                   root_al, max_stack);
        if (ret)
@@ -1938,7 +1953,7 @@ int thread__resolve_callchain(struct thread *thread,
            (!sample->user_stack.size))
                return 0;
 
-       return unwind__get_entries(unwind_entry, &callchain_cursor,
+       return unwind__get_entries(unwind_entry, cursor,
                                   thread, sample, max_stack);
 
 }
This page took 0.029682 seconds and 5 git commands to generate.