aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/thread-stack.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index d93cd286b048..a5f7b9d8fc23 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -60,6 +60,7 @@ struct thread_stack_entry {
60 * @last_time: last timestamp 60 * @last_time: last timestamp
61 * @crp: call/return processor 61 * @crp: call/return processor
62 * @comm: current comm 62 * @comm: current comm
63 * @arr_sz: size of array if this is the first element of an array
63 */ 64 */
64struct thread_stack { 65struct thread_stack {
65 struct thread_stack_entry *stack; 66 struct thread_stack_entry *stack;
@@ -71,6 +72,7 @@ struct thread_stack {
71 u64 last_time; 72 u64 last_time;
72 struct call_return_processor *crp; 73 struct call_return_processor *crp;
73 struct comm *comm; 74 struct comm *comm;
75 unsigned int arr_sz;
74}; 76};
75 77
76static int thread_stack__grow(struct thread_stack *ts) 78static int thread_stack__grow(struct thread_stack *ts)
@@ -100,6 +102,8 @@ static struct thread_stack *thread_stack__new(struct thread *thread,
100 if (!ts) 102 if (!ts)
101 return NULL; 103 return NULL;
102 104
105 ts->arr_sz = 1;
106
103 if (thread_stack__grow(ts)) { 107 if (thread_stack__grow(ts)) {
104 free(ts); 108 free(ts);
105 return NULL; 109 return NULL;
@@ -234,11 +238,19 @@ static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts)
234int thread_stack__flush(struct thread *thread) 238int thread_stack__flush(struct thread *thread)
235{ 239{
236 struct thread_stack *ts = thread->ts; 240 struct thread_stack *ts = thread->ts;
241 unsigned int pos;
242 int err = 0;
237 243
238 if (ts) 244 if (ts) {
239 return __thread_stack__flush(thread, ts); 245 for (pos = 0; pos < ts->arr_sz; pos++) {
246 int ret = __thread_stack__flush(thread, ts + pos);
240 247
241 return 0; 248 if (ret)
249 err = ret;
250 }
251 }
252
253 return err;
242} 254}
243 255
244int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, 256int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
@@ -314,13 +326,29 @@ void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr)
314 } 326 }
315} 327}
316 328
329static void __thread_stack__free(struct thread *thread, struct thread_stack *ts)
330{
331 __thread_stack__flush(thread, ts);
332 zfree(&ts->stack);
333}
334
335static void thread_stack__reset(struct thread *thread, struct thread_stack *ts)
336{
337 unsigned int arr_sz = ts->arr_sz;
338
339 __thread_stack__free(thread, ts);
340 memset(ts, 0, sizeof(*ts));
341 ts->arr_sz = arr_sz;
342}
343
317void thread_stack__free(struct thread *thread) 344void thread_stack__free(struct thread *thread)
318{ 345{
319 struct thread_stack *ts = thread->ts; 346 struct thread_stack *ts = thread->ts;
347 unsigned int pos;
320 348
321 if (ts) { 349 if (ts) {
322 __thread_stack__flush(thread, ts); 350 for (pos = 0; pos < ts->arr_sz; pos++)
323 zfree(&ts->stack); 351 __thread_stack__free(thread, ts + pos);
324 zfree(&thread->ts); 352 zfree(&thread->ts);
325 } 353 }
326} 354}
@@ -611,7 +639,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm,
611 639
612 if (ts && !ts->crp) { 640 if (ts && !ts->crp) {
613 /* Supersede thread_stack__event() */ 641 /* Supersede thread_stack__event() */
614 thread_stack__free(thread); 642 thread_stack__reset(thread, ts);
615 ts = NULL; 643 ts = NULL;
616 } 644 }
617 645