Release 4.10 tools/perf/util/thread.c
#include "../perf.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "session.h"
#include "thread.h"
#include "thread-stack.h"
#include "util.h"
#include "debug.h"
#include "comm.h"
#include "unwind.h"
#include <api/fs/fs.h>
int thread__init_map_groups(struct thread *thread, struct machine *machine)
{
pid_t pid = thread->pid_;
if (pid == thread->tid || pid == -1) {
thread->mg = map_groups__new(machine);
} else {
struct thread *leader = __machine__findnew_thread(machine, pid, pid);
if (leader) {
thread->mg = map_groups__get(leader->mg);
thread__put(leader);
}
}
return thread->mg ? 0 : -1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 74 | 77.89% | 1 | 16.67% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 16 | 16.84% | 4 | 66.67% |
adrian hunter | adrian hunter | 5 | 5.26% | 1 | 16.67% |
| Total | 95 | 100.00% | 6 | 100.00% |
struct thread *thread__new(pid_t pid, pid_t tid)
{
char *comm_str;
struct comm *comm;
struct thread *thread = zalloc(sizeof(*thread));
if (thread != NULL) {
thread->pid_ = pid;
thread->tid = tid;
thread->ppid = -1;
thread->cpu = -1;
INIT_LIST_HEAD(&thread->comm_list);
comm_str = malloc(32);
if (!comm_str)
goto err_thread;
snprintf(comm_str, 32, ":%d", tid);
comm = comm__new(comm_str, 0, false);
free(comm_str);
if (!comm)
goto err_thread;
list_add(&comm->list, &thread->comm_list);
atomic_set(&thread->refcnt, 1);
RB_CLEAR_NODE(&thread->rb_node);
}
return thread;
err_thread:
free(thread);
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 114 | 66.28% | 2 | 15.38% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 32 | 18.60% | 6 | 46.15% |
adrian hunter | adrian hunter | 20 | 11.63% | 4 | 30.77% |
david ahern | david ahern | 6 | 3.49% | 1 | 7.69% |
| Total | 172 | 100.00% | 13 | 100.00% |
void thread__delete(struct thread *thread)
{
struct comm *comm, *tmp;
BUG_ON(!RB_EMPTY_NODE(&thread->rb_node));
thread_stack__free(thread);
if (thread->mg) {
map_groups__put(thread->mg);
thread->mg = NULL;
}
list_for_each_entry_safe(comm, tmp, &thread->comm_list, list) {
list_del(&comm->list);
comm__free(comm);
}
unwind__finish_access(thread);
free(thread);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 45 | 49.45% | 5 | 55.56% |
frederic weisbecker | frederic weisbecker | 28 | 30.77% | 1 | 11.11% |
adrian hunter | adrian hunter | 13 | 14.29% | 2 | 22.22% |
namhyung kim | namhyung kim | 5 | 5.49% | 1 | 11.11% |
| Total | 91 | 100.00% | 9 | 100.00% |
struct thread *thread__get(struct thread *thread)
{
if (thread)
atomic_inc(&thread->refcnt);
return thread;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 27 | 100.00% | 3 | 100.00% |
| Total | 27 | 100.00% | 3 | 100.00% |
void thread__put(struct thread *thread)
{
if (thread && atomic_dec_and_test(&thread->refcnt)) {
/*
* Remove it from the dead_threads list, as last reference
* is gone.
*/
list_del_init(&thread->node);
thread__delete(thread);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 38 | 100.00% | 3 | 100.00% |
| Total | 38 | 100.00% | 3 | 100.00% |
struct comm *thread__comm(const struct thread *thread)
{
if (list_empty(&thread->comm_list))
return NULL;
return list_first_entry(&thread->comm_list, struct comm, list);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 40 | 100.00% | 1 | 100.00% |
| Total | 40 | 100.00% | 1 | 100.00% |
struct comm *thread__exec_comm(const struct thread *thread)
{
struct comm *comm, *last = NULL;
list_for_each_entry(comm, &thread->comm_list, list) {
if (comm->exec)
return comm;
last = comm;
}
return last;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
adrian hunter | adrian hunter | 49 | 100.00% | 1 | 100.00% |
| Total | 49 | 100.00% | 1 | 100.00% |
int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
bool exec)
{
struct comm *new, *curr = thread__comm(thread);
/* Override the default :tid entry */
if (!thread->comm_set) {
int err = comm__override(curr, str, timestamp, exec);
if (err)
return err;
} else {
new = comm__new(str, timestamp, exec);
if (!new)
return -ENOMEM;
list_add(&new->list, &thread->comm_list);
if (exec)
unwind__flush_access(thread);
}
thread->comm_set = true;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 74 | 62.18% | 5 | 38.46% |
namhyung kim | namhyung kim | 14 | 11.76% | 2 | 15.38% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 12 | 10.08% | 3 | 23.08% |
adrian hunter | adrian hunter | 12 | 10.08% | 2 | 15.38% |
david s. miller | david s. miller | 7 | 5.88% | 1 | 7.69% |
| Total | 119 | 100.00% | 13 | 100.00% |
int thread__set_comm_from_proc(struct thread *thread)
{
char path[64];
char *comm = NULL;
size_t sz;
int err = -1;
if (!(snprintf(path, sizeof(path), "%d/task/%d/comm",
thread->pid_, thread->tid) >= (int)sizeof(path)) &&
procfs__read_str(path, &comm, &sz) == 0) {
comm[sz - 1] = '\0';
err = thread__set_comm(thread, comm, 0);
}
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 102 | 100.00% | 1 | 100.00% |
| Total | 102 | 100.00% | 1 | 100.00% |
const char *thread__comm_str(const struct thread *thread)
{
const struct comm *comm = thread__comm(thread);
if (!comm)
return NULL;
return comm__str(comm);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 38 | 100.00% | 2 | 100.00% |
| Total | 38 | 100.00% | 2 | 100.00% |
/* CHECKME: it should probably better return the max comm len from its comm list */
int thread__comm_len(struct thread *thread)
{
if (!thread->comm_len) {
const char *comm = thread__comm_str(thread);
if (!comm)
return 0;
thread->comm_len = strlen(comm);
}
return thread->comm_len;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 47 | 92.16% | 2 | 66.67% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 4 | 7.84% | 1 | 33.33% |
| Total | 51 | 100.00% | 3 | 100.00% |
size_t thread__fprintf(struct thread *thread, FILE *fp)
{
return fprintf(fp, "Thread %d %s\n", thread->tid, thread__comm_str(thread)) +
map_groups__fprintf(thread->mg, fp);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
frederic weisbecker | frederic weisbecker | 20 | 50.00% | 2 | 28.57% |
arnaldo carvalho de melo | arnaldo carvalho de melo | 19 | 47.50% | 4 | 57.14% |
adrian hunter | adrian hunter | 1 | 2.50% | 1 | 14.29% |
| Total | 40 | 100.00% | 7 | 100.00% |
int thread__insert_map(struct thread *thread, struct map *map)
{
int ret;
ret = unwind__prepare_access(thread, map, NULL);
if (ret)
return ret;
map_groups__fixup_overlappings(thread->mg, map, stderr);
map_groups__insert(thread->mg, map);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 30 | 50.85% | 5 | 55.56% |
he kuang | he kuang | 23 | 38.98% | 2 | 22.22% |
frederic weisbecker | frederic weisbecker | 4 | 6.78% | 1 | 11.11% |
jiri olsa | jiri olsa | 2 | 3.39% | 1 | 11.11% |
| Total | 59 | 100.00% | 9 | 100.00% |
static int __thread__prepare_access(struct thread *thread)
{
bool initialized = false;
int i, err = 0;
for (i = 0; i < MAP__NR_TYPES; ++i) {
struct maps *maps = &thread->mg->maps[i];
struct map *map;
pthread_rwlock_rdlock(&maps->lock);
for (map = maps__first(maps); map; map = map__next(map)) {
err = unwind__prepare_access(thread, map, &initialized);
if (err || initialized)
break;
}
pthread_rwlock_unlock(&maps->lock);
}
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 116 | 100.00% | 1 | 100.00% |
| Total | 116 | 100.00% | 1 | 100.00% |
static int thread__prepare_access(struct thread *thread)
{
int err = 0;
if (symbol_conf.use_callchain)
err = __thread__prepare_access(thread);
return err;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 32 | 100.00% | 1 | 100.00% |
| Total | 32 | 100.00% | 1 | 100.00% |
static int thread__clone_map_groups(struct thread *thread,
struct thread *parent)
{
int i;
/* This is new thread, we share map groups for process. */
if (thread->pid_ == parent->pid_)
return thread__prepare_access(thread);
if (thread->mg == parent->mg) {
pr_debug("broken map groups on thread %d/%d parent %d/%d\n",
thread->pid_, thread->tid, parent->pid_, parent->tid);
return 0;
}
/* But this one is new process, copy maps. */
for (i = 0; i < MAP__NR_TYPES; ++i)
if (map_groups__clone(thread, parent->mg, i) < 0)
return -ENOMEM;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jiri olsa | jiri olsa | 72 | 66.67% | 2 | 66.67% |
adrian hunter | adrian hunter | 36 | 33.33% | 1 | 33.33% |
| Total | 108 | 100.00% | 3 | 100.00% |
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp)
{
if (parent->comm_set) {
const char *comm = thread__comm_str(parent);
int err;
if (!comm)
return -ENOMEM;
err = thread__set_comm(thread, comm, timestamp);
if (err)
return err;
}
thread->ppid = parent->tid;
return thread__clone_map_groups(thread, parent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 43 | 52.44% | 4 | 44.44% |
frederic weisbecker | frederic weisbecker | 26 | 31.71% | 2 | 22.22% |
david ahern | david ahern | 6 | 7.32% | 1 | 11.11% |
jiri olsa | jiri olsa | 6 | 7.32% | 1 | 11.11% |
adrian hunter | adrian hunter | 1 | 1.22% | 1 | 11.11% |
| Total | 82 | 100.00% | 9 | 100.00% |
void thread__find_cpumode_addr_location(struct thread *thread,
enum map_type type, u64 addr,
struct addr_location *al)
{
size_t i;
const u8 cpumodes[] = {
PERF_RECORD_MISC_USER,
PERF_RECORD_MISC_KERNEL,
PERF_RECORD_MISC_GUEST_USER,
PERF_RECORD_MISC_GUEST_KERNEL
};
for (i = 0; i < ARRAY_SIZE(cpumodes); i++) {
thread__find_addr_location(thread, cpumodes[i], type, addr, al);
if (al->map)
break;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 81 | 100.00% | 1 | 100.00% |
| Total | 81 | 100.00% | 1 | 100.00% |
struct thread *thread__main_thread(struct machine *machine, struct thread *thread)
{
if (thread->pid_ == thread->tid)
return thread__get(thread);
if (thread->pid_ == -1)
return NULL;
return machine__find_thread(machine, thread->pid_, thread->pid_);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
andi kleen | andi kleen | 59 | 100.00% | 1 | 100.00% |
| Total | 59 | 100.00% | 1 | 100.00% |
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
arnaldo carvalho de melo | arnaldo carvalho de melo | 455 | 31.69% | 21 | 42.86% |
frederic weisbecker | frederic weisbecker | 416 | 28.97% | 8 | 16.33% |
jiri olsa | jiri olsa | 302 | 21.03% | 3 | 6.12% |
adrian hunter | adrian hunter | 140 | 9.75% | 9 | 18.37% |
andi kleen | andi kleen | 59 | 4.11% | 1 | 2.04% |
he kuang | he kuang | 23 | 1.60% | 2 | 4.08% |
namhyung kim | namhyung kim | 22 | 1.53% | 3 | 6.12% |
david ahern | david ahern | 12 | 0.84% | 1 | 2.04% |
david s. miller | david s. miller | 7 | 0.49% | 1 | 2.04% |
| Total | 1436 | 100.00% | 49 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.