Lines Matching full:thread
2 * thread-stack.c: Synthesize a thread's stack using call / return events
19 #include "thread.h"
27 #include "thread-stack.h"
32 * struct thread_stack_entry - thread stack entry.
50 * struct thread_stack - thread stack constructed from 'call' and 'return'
92 static struct thread_stack *thread_stack__new(struct thread *thread, in thread_stack__new() argument
106 if (thread->mg && thread->mg->machine) in thread_stack__new()
107 ts->kernel_start = machine__kernel_start(thread->mg->machine); in thread_stack__new()
122 pr_warning("Out of memory: discarding thread stack\n"); in thread_stack__push()
161 static int thread_stack__call_return(struct thread *thread, in thread_stack__call_return() argument
168 .thread = thread, in thread_stack__call_return()
188 static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts) in __thread_stack__flush() argument
199 err = thread_stack__call_return(thread, ts, --ts->cnt, in __thread_stack__flush()
202 pr_err("Error flushing thread stack!\n"); in __thread_stack__flush()
211 int thread_stack__flush(struct thread *thread) in thread_stack__flush() argument
213 if (thread->ts) in thread_stack__flush()
214 return __thread_stack__flush(thread, thread->ts); in thread_stack__flush()
219 int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, in thread_stack__event() argument
222 if (!thread) in thread_stack__event()
225 if (!thread->ts) { in thread_stack__event()
226 thread->ts = thread_stack__new(thread, NULL); in thread_stack__event()
227 if (!thread->ts) { in thread_stack__event()
228 pr_warning("Out of memory: no thread stack\n"); in thread_stack__event()
231 thread->ts->trace_nr = trace_nr; in thread_stack__event()
239 if (trace_nr != thread->ts->trace_nr) { in thread_stack__event()
240 if (thread->ts->trace_nr) in thread_stack__event()
241 __thread_stack__flush(thread, thread->ts); in thread_stack__event()
242 thread->ts->trace_nr = trace_nr; in thread_stack__event()
246 if (thread->ts->crp) in thread_stack__event()
257 return thread_stack__push(thread->ts, ret_addr); in thread_stack__event()
261 thread_stack__pop(thread->ts, to_ip); in thread_stack__event()
267 void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr) in thread_stack__set_trace_nr() argument
269 if (!thread || !thread->ts) in thread_stack__set_trace_nr()
272 if (trace_nr != thread->ts->trace_nr) { in thread_stack__set_trace_nr()
273 if (thread->ts->trace_nr) in thread_stack__set_trace_nr()
274 __thread_stack__flush(thread, thread->ts); in thread_stack__set_trace_nr()
275 thread->ts->trace_nr = trace_nr; in thread_stack__set_trace_nr()
279 void thread_stack__free(struct thread *thread) in thread_stack__free() argument
281 if (thread->ts) { in thread_stack__free()
282 __thread_stack__flush(thread, thread->ts); in thread_stack__free()
283 zfree(&thread->ts->stack); in thread_stack__free()
284 zfree(&thread->ts); in thread_stack__free()
293 void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, in thread_stack__sample() argument
308 if (!thread || !thread->ts) { in thread_stack__sample()
315 for (i = 2, j = 1; i < sz && j <= thread->ts->cnt; i++, j++) { in thread_stack__sample()
316 ip = thread->ts->stack[thread->ts->cnt - j].ret_addr; in thread_stack__sample()
383 static int thread_stack__pop_cp(struct thread *thread, struct thread_stack *ts, in thread_stack__pop_cp() argument
396 return thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__pop_cp()
401 return thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__pop_cp()
411 err = thread_stack__call_return(thread, ts, in thread_stack__pop_cp()
418 return thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__pop_cp()
426 static int thread_stack__bottom(struct thread *thread, struct thread_stack *ts, in thread_stack__bottom() argument
451 return thread_stack__push_cp(thread->ts, ip, sample->time, ref, cp, in thread_stack__bottom()
455 static int thread_stack__no_call_return(struct thread *thread, in thread_stack__no_call_return() argument
469 err = thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__no_call_return()
489 err = thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__no_call_return()
513 return thread_stack__pop_cp(thread, ts, sample->addr, sample->time, ref, in thread_stack__no_call_return()
517 static int thread_stack__trace_begin(struct thread *thread, in thread_stack__trace_begin() argument
530 err = thread_stack__call_return(thread, ts, --ts->cnt, in thread_stack__trace_begin()
561 int thread_stack__process(struct thread *thread, struct comm *comm, in thread_stack__process() argument
567 struct thread_stack *ts = thread->ts; in thread_stack__process()
573 thread_stack__free(thread); in thread_stack__process()
574 thread->ts = thread_stack__new(thread, crp); in thread_stack__process()
575 if (!thread->ts) in thread_stack__process()
577 ts = thread->ts; in thread_stack__process()
581 thread->ts = thread_stack__new(thread, crp); in thread_stack__process()
582 if (!thread->ts) in thread_stack__process()
584 ts = thread->ts; in thread_stack__process()
589 if (ts->comm != comm && thread->pid_ == thread->tid) { in thread_stack__process()
590 err = __thread_stack__flush(thread, ts); in thread_stack__process()
598 err = thread_stack__bottom(thread, ts, sample, from_al, to_al, in thread_stack__process()
630 err = thread_stack__pop_cp(thread, ts, sample->addr, in thread_stack__process()
635 err = thread_stack__no_call_return(thread, ts, sample, in thread_stack__process()
639 err = thread_stack__trace_begin(thread, ts, sample->time, ref); in thread_stack__process()
647 size_t thread_stack__depth(struct thread *thread) in thread_stack__depth() argument
649 if (!thread->ts) in thread_stack__depth()
651 return thread->ts->cnt; in thread_stack__depth()