^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __PERF_THREAD_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __PERF_THREAD_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/refcount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/rbtree.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "srccode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "symbol_conf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <strlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <intlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "rwsem.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "callchain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct addr_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct perf_record_namespaces;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct thread_stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct unwind_libunwind_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct lbr_stitch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct list_head lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct list_head free_lists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct perf_sample prev_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct callchain_cursor_node *prev_lbr_cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct thread {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct rb_node rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct maps *maps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) pid_t pid_; /* Not all tools update this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) pid_t tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pid_t ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) refcount_t refcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) bool comm_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int comm_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) bool dead; /* if set thread has exited */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct list_head namespaces_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct rw_semaphore namespaces_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct list_head comm_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct rw_semaphore comm_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u64 db_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct thread_stack *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct nsinfo *nsinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct srccode_state srccode_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) bool filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int filter_entry_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* LBR call stack stitch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) bool lbr_stitch_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct lbr_stitch *lbr_stitch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct machine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct namespaces;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct thread *thread__new(pid_t pid, pid_t tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int thread__init_maps(struct thread *thread, struct machine *machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) void thread__delete(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct thread *thread__get(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void thread__put(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline void __thread__zput(struct thread **thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) thread__put(*thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define thread__zput(thread) __thread__zput(&thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static inline void thread__exited(struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) thread->dead = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct namespaces *thread__namespaces(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int thread__set_namespaces(struct thread *thread, u64 timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct perf_record_namespaces *event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bool exec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline int thread__set_comm(struct thread *thread, const char *comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u64 timestamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return __thread__set_comm(thread, comm, timestamp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int thread__set_comm_from_proc(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int thread__comm_len(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct comm *thread__comm(const struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct comm *thread__exec_comm(const struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const char *thread__comm_str(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int thread__insert_map(struct thread *thread, struct map *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) size_t thread__fprintf(struct thread *thread, FILE *fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct thread *thread__main_thread(struct machine *machine, struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct addr_location *al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct addr_location *al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u64 addr, struct addr_location *al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u64 addr, struct addr_location *al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) void thread__find_cpumode_addr_location(struct thread *thread, u64 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct addr_location *al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int thread__memcpy(struct thread *thread, struct machine *machine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) void *buf, u64 ip, int len, bool *is64bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static inline void *thread__priv(struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return thread->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static inline void thread__set_priv(struct thread *thread, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) thread->priv = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static inline bool thread__is_filtered(struct thread *thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (symbol_conf.comm_list &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (symbol_conf.pid_list &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) !intlist__has_entry(symbol_conf.pid_list, thread->pid_)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (symbol_conf.tid_list &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) !intlist__has_entry(symbol_conf.tid_list, thread->tid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void thread__free_stitch_list(struct thread *thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #endif /* __PERF_THREAD_H */