1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef __PERF_THREAD_H 3 #define __PERF_THREAD_H 4 5 #include <linux/refcount.h> 6 #include <linux/rbtree.h> 7 #include <linux/list.h> 8 #include <stdio.h> 9 #include <unistd.h> 10 #include <sys/types.h> 11 #include "srccode.h" 12 #include "symbol_conf.h" 13 #include <strlist.h> 14 #include <intlist.h> 15 #include "rwsem.h" 16 #include "event.h" 17 #include "callchain.h" 18 #include <internal/rc_check.h> 19 20 struct addr_location; 21 struct map; 22 struct perf_record_namespaces; 23 struct thread_stack; 24 struct unwind_libunwind_ops; 25 26 struct lbr_stitch { 27 struct list_head lists; 28 struct list_head free_lists; 29 struct perf_sample prev_sample; 30 struct callchain_cursor_node *prev_lbr_cursor; 31 }; 32 33 struct thread_rb_node { 34 struct rb_node rb_node; 35 struct thread *thread; 36 }; 37 38 DECLARE_RC_STRUCT(thread) { 39 struct maps *maps; 40 pid_t pid_; /* Not all tools update this */ 41 pid_t tid; 42 pid_t ppid; 43 int cpu; 44 int guest_cpu; /* For QEMU thread */ 45 refcount_t refcnt; 46 bool comm_set; 47 int comm_len; 48 struct list_head namespaces_list; 49 struct rw_semaphore namespaces_lock; 50 struct list_head comm_list; 51 struct rw_semaphore comm_lock; 52 u64 db_id; 53 54 void *priv; 55 struct thread_stack *ts; 56 struct nsinfo *nsinfo; 57 struct srccode_state srccode_state; 58 bool filter; 59 int filter_entry_depth; 60 61 /* LBR call stack stitch */ 62 bool lbr_stitch_enable; 63 struct lbr_stitch *lbr_stitch; 64 }; 65 66 struct machine; 67 struct namespaces; 68 struct comm; 69 70 struct thread *thread__new(pid_t pid, pid_t tid); 71 int thread__init_maps(struct thread *thread, struct machine *machine); 72 void thread__delete(struct thread *thread); 73 74 void thread__set_priv_destructor(void (*destructor)(void *priv)); 75 76 struct thread *thread__get(struct thread *thread); 77 void thread__put(struct thread *thread); 78 79 static inline void __thread__zput(struct thread **thread) 80 { 81 thread__put(*thread); 82 *thread = NULL; 83 } 84 85 #define thread__zput(thread) __thread__zput(&thread) 86 87 struct namespaces *thread__namespaces(struct thread *thread); 88 int thread__set_namespaces(struct thread *thread, u64 timestamp, 89 struct perf_record_namespaces *event); 90 91 int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, 92 bool exec); 93 static inline int thread__set_comm(struct thread *thread, const char *comm, 94 u64 timestamp) 95 { 96 return __thread__set_comm(thread, comm, timestamp, false); 97 } 98 99 int thread__set_comm_from_proc(struct thread *thread); 100 101 int thread__comm_len(struct thread *thread); 102 struct comm *thread__comm(struct thread *thread); 103 struct comm *thread__exec_comm(struct thread *thread); 104 const char *thread__comm_str(struct thread *thread); 105 int thread__insert_map(struct thread *thread, struct map *map); 106 int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp, bool do_maps_clone); 107 size_t thread__fprintf(struct thread *thread, FILE *fp); 108 109 struct thread *thread__main_thread(struct machine *machine, struct thread *thread); 110 111 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 112 struct addr_location *al); 113 struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, 114 struct addr_location *al); 115 116 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 117 u64 addr, struct addr_location *al); 118 struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, 119 u64 addr, struct addr_location *al); 120 121 void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, 122 struct addr_location *al); 123 124 int thread__memcpy(struct thread *thread, struct machine *machine, 125 void *buf, u64 ip, int len, bool *is64bit); 126 127 static inline struct maps *thread__maps(struct thread *thread) 128 { 129 return RC_CHK_ACCESS(thread)->maps; 130 } 131 132 static inline void thread__set_maps(struct thread *thread, struct maps *maps) 133 { 134 RC_CHK_ACCESS(thread)->maps = maps; 135 } 136 137 static inline pid_t thread__pid(const struct thread *thread) 138 { 139 return RC_CHK_ACCESS(thread)->pid_; 140 } 141 142 static inline void thread__set_pid(struct thread *thread, pid_t pid_) 143 { 144 RC_CHK_ACCESS(thread)->pid_ = pid_; 145 } 146 147 static inline pid_t thread__tid(const struct thread *thread) 148 { 149 return RC_CHK_ACCESS(thread)->tid; 150 } 151 152 static inline void thread__set_tid(struct thread *thread, pid_t tid) 153 { 154 RC_CHK_ACCESS(thread)->tid = tid; 155 } 156 157 static inline pid_t thread__ppid(const struct thread *thread) 158 { 159 return RC_CHK_ACCESS(thread)->ppid; 160 } 161 162 static inline void thread__set_ppid(struct thread *thread, pid_t ppid) 163 { 164 RC_CHK_ACCESS(thread)->ppid = ppid; 165 } 166 167 static inline int thread__cpu(const struct thread *thread) 168 { 169 return RC_CHK_ACCESS(thread)->cpu; 170 } 171 172 static inline void thread__set_cpu(struct thread *thread, int cpu) 173 { 174 RC_CHK_ACCESS(thread)->cpu = cpu; 175 } 176 177 static inline int thread__guest_cpu(const struct thread *thread) 178 { 179 return RC_CHK_ACCESS(thread)->guest_cpu; 180 } 181 182 static inline void thread__set_guest_cpu(struct thread *thread, int guest_cpu) 183 { 184 RC_CHK_ACCESS(thread)->guest_cpu = guest_cpu; 185 } 186 187 static inline refcount_t *thread__refcnt(struct thread *thread) 188 { 189 return &RC_CHK_ACCESS(thread)->refcnt; 190 } 191 192 static inline bool thread__comm_set(const struct thread *thread) 193 { 194 return RC_CHK_ACCESS(thread)->comm_set; 195 } 196 197 static inline void thread__set_comm_set(struct thread *thread, bool set) 198 { 199 RC_CHK_ACCESS(thread)->comm_set = set; 200 } 201 202 static inline int thread__var_comm_len(const struct thread *thread) 203 { 204 return RC_CHK_ACCESS(thread)->comm_len; 205 } 206 207 static inline void thread__set_comm_len(struct thread *thread, int len) 208 { 209 RC_CHK_ACCESS(thread)->comm_len = len; 210 } 211 212 static inline struct list_head *thread__namespaces_list(struct thread *thread) 213 { 214 return &RC_CHK_ACCESS(thread)->namespaces_list; 215 } 216 217 static inline int thread__namespaces_list_empty(const struct thread *thread) 218 { 219 return list_empty(&RC_CHK_ACCESS(thread)->namespaces_list); 220 } 221 222 static inline struct rw_semaphore *thread__namespaces_lock(struct thread *thread) 223 { 224 return &RC_CHK_ACCESS(thread)->namespaces_lock; 225 } 226 227 static inline struct list_head *thread__comm_list(struct thread *thread) 228 { 229 return &RC_CHK_ACCESS(thread)->comm_list; 230 } 231 232 static inline struct rw_semaphore *thread__comm_lock(struct thread *thread) 233 { 234 return &RC_CHK_ACCESS(thread)->comm_lock; 235 } 236 237 static inline u64 thread__db_id(const struct thread *thread) 238 { 239 return RC_CHK_ACCESS(thread)->db_id; 240 } 241 242 static inline void thread__set_db_id(struct thread *thread, u64 db_id) 243 { 244 RC_CHK_ACCESS(thread)->db_id = db_id; 245 } 246 247 static inline void *thread__priv(struct thread *thread) 248 { 249 return RC_CHK_ACCESS(thread)->priv; 250 } 251 252 static inline void thread__set_priv(struct thread *thread, void *p) 253 { 254 RC_CHK_ACCESS(thread)->priv = p; 255 } 256 257 static inline struct thread_stack *thread__ts(struct thread *thread) 258 { 259 return RC_CHK_ACCESS(thread)->ts; 260 } 261 262 static inline void thread__set_ts(struct thread *thread, struct thread_stack *ts) 263 { 264 RC_CHK_ACCESS(thread)->ts = ts; 265 } 266 267 static inline struct nsinfo *thread__nsinfo(struct thread *thread) 268 { 269 return RC_CHK_ACCESS(thread)->nsinfo; 270 } 271 272 static inline struct srccode_state *thread__srccode_state(struct thread *thread) 273 { 274 return &RC_CHK_ACCESS(thread)->srccode_state; 275 } 276 277 static inline bool thread__filter(const struct thread *thread) 278 { 279 return RC_CHK_ACCESS(thread)->filter; 280 } 281 282 static inline void thread__set_filter(struct thread *thread, bool filter) 283 { 284 RC_CHK_ACCESS(thread)->filter = filter; 285 } 286 287 static inline int thread__filter_entry_depth(const struct thread *thread) 288 { 289 return RC_CHK_ACCESS(thread)->filter_entry_depth; 290 } 291 292 static inline void thread__set_filter_entry_depth(struct thread *thread, int depth) 293 { 294 RC_CHK_ACCESS(thread)->filter_entry_depth = depth; 295 } 296 297 static inline bool thread__lbr_stitch_enable(const struct thread *thread) 298 { 299 return RC_CHK_ACCESS(thread)->lbr_stitch_enable; 300 } 301 302 static inline void thread__set_lbr_stitch_enable(struct thread *thread, bool en) 303 { 304 RC_CHK_ACCESS(thread)->lbr_stitch_enable = en; 305 } 306 307 static inline struct lbr_stitch *thread__lbr_stitch(struct thread *thread) 308 { 309 return RC_CHK_ACCESS(thread)->lbr_stitch; 310 } 311 312 static inline void thread__set_lbr_stitch(struct thread *thread, struct lbr_stitch *lbrs) 313 { 314 RC_CHK_ACCESS(thread)->lbr_stitch = lbrs; 315 } 316 317 static inline bool thread__is_filtered(struct thread *thread) 318 { 319 if (symbol_conf.comm_list && 320 !strlist__has_entry(symbol_conf.comm_list, thread__comm_str(thread))) { 321 return true; 322 } 323 324 if (symbol_conf.pid_list && 325 !intlist__has_entry(symbol_conf.pid_list, thread__pid(thread))) { 326 return true; 327 } 328 329 if (symbol_conf.tid_list && 330 !intlist__has_entry(symbol_conf.tid_list, thread__tid(thread))) { 331 return true; 332 } 333 334 return false; 335 } 336 337 void thread__free_stitch_list(struct thread *thread); 338 339 void thread__resolve(struct thread *thread, struct addr_location *al, 340 struct perf_sample *sample); 341 342 #endif /* __PERF_THREAD_H */ 343