if (timestamp && curr) { /* * setns syscall must have changed few or all the namespaces * of this thread. Update end time for the namespaces * previously used.
*/
curr = list_next_entry(new, list);
curr->end_time = timestamp;
}
return 0;
}
int thread__set_namespaces(struct thread *thread, u64 timestamp, struct perf_record_namespaces *event)
{ int ret;
down_write(thread__namespaces_lock(thread));
ret = __thread__set_namespaces(thread, timestamp, event);
up_write(thread__namespaces_lock(thread)); return ret;
}
staticstruct comm *__thread__comm(struct thread *thread)
SHARED_LOCKS_REQUIRED(thread__comm_lock(thread))
{ if (list_empty(thread__comm_list(thread))) return NULL;
struct comm *thread__comm(struct thread *thread)
{ struct comm *res = NULL;
down_read(thread__comm_lock(thread));
res = __thread__comm(thread);
up_read(thread__comm_lock(thread)); return res;
}
struct comm *thread__exec_comm(struct thread *thread)
{ struct comm *comm, *last = NULL, *second_last = NULL;
down_read(thread__comm_lock(thread));
list_for_each_entry(comm, thread__comm_list(thread), list) { if (comm->exec) {
up_read(thread__comm_lock(thread)); return comm;
}
second_last = last;
last = comm;
}
up_read(thread__comm_lock(thread));
/* * 'last' with no start time might be the parent's comm of a synthesized * thread (created by processing a synthesized fork event). For a main * thread, that is very probably wrong. Prefer a later comm to avoid * that case.
*/ if (second_last && !last->start && thread__pid(thread) == thread__tid(thread)) return second_last;
/* CHECKME: it should probably better return the max comm len from its comm list */ int thread__comm_len(struct thread *thread)
{ int comm_len = thread__var_comm_len(thread);
if (!comm_len) { constchar *comm;
down_read(thread__comm_lock(thread));
comm = __thread__comm_str(thread);
comm_len = __thread__comm_len(thread, comm);
up_read(thread__comm_lock(thread));
}
if (dwarf_callchain_users) {
args.maps = thread__maps(thread);
maps__for_each_map(thread__maps(thread), thread__prepare_access_maps_cb, &args);
}
return args.err;
}
staticint thread__clone_maps(struct thread *thread, struct thread *parent, bool do_maps_clone)
{ /* This is new thread, we share map groups for process. */ if (thread__pid(thread) == thread__pid(parent)) return thread__prepare_access(thread);
if (maps__equal(thread__maps(thread), thread__maps(parent))) {
pr_debug("broken map groups on thread %d/%d parent %d/%d\n",
thread__pid(thread), thread__tid(thread),
thread__pid(parent), thread__tid(parent)); return 0;
} /* But this one is new process, copy maps. */ return do_maps_clone ? maps__copy_from(thread__maps(thread), thread__maps(parent)) : 0;
}
int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone)
{ if (thread__comm_set(parent)) { constchar *comm = thread__comm_str(parent); int err; if (!comm) return -ENOMEM;
err = thread__set_comm(thread, comm, timestamp); if (err) return err;
}
for (i = 0; i < ARRAY_SIZE(cpumodes); i++) { if (symbols)
thread__find_symbol(thread, cpumodes[i], addr, al); else
thread__find_map(thread, cpumodes[i], addr, al);
if (al->map) break;
}
}
static uint16_t read_proc_e_machine_for_pid(pid_t pid)
{ char path[6 /* "/proc/" */ + 11 /* max length of pid */ + 5 /* "/exe\0" */]; int fd;
uint16_t e_machine = EM_NONE;
tid = thread__tid(thread);
pid = thread__pid(thread); if (pid != tid) { struct thread *parent = machine__findnew_thread(machine, pid, pid);
if (parent) {
e_machine = thread__e_machine(parent, machine);
thread__put(parent);
thread__set_e_machine(thread, e_machine); return e_machine;
} /* Something went wrong, fallback. */
} /* Reading on the PID thread. First try to find from the maps. */
e_machine = maps__for_each_map(thread__maps(thread),
thread__e_machine_callback,
machine); if (e_machine == EM_NONE) { /* Maps failed, perhaps we're live with map events disabled. */ bool is_live = machine->machines == NULL;
if (!is_live) { /* Check if the session has a data file. */ struct perf_session *session = container_of(machine->machines, struct perf_session,
machines);
is_live = !!session->data;
} /* Read from /proc/pid/exe if live. */ if (is_live)
e_machine = read_proc_e_machine_for_pid(pid);
} if (e_machine != EM_NONE)
thread__set_e_machine(thread, e_machine); else
e_machine = EM_HOST; return e_machine;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.