diff options
| -rw-r--r-- | tools/perf/util/thread-stack.c | 40 |
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 | */ |
| 64 | struct thread_stack { | 65 | struct 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 | ||
| 76 | static int thread_stack__grow(struct thread_stack *ts) | 78 | static 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) | |||
| 234 | int thread_stack__flush(struct thread *thread) | 238 | int 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 | ||
| 244 | int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | 256 | int 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 | ||
| 329 | static void __thread_stack__free(struct thread *thread, struct thread_stack *ts) | ||
| 330 | { | ||
| 331 | __thread_stack__flush(thread, ts); | ||
| 332 | zfree(&ts->stack); | ||
| 333 | } | ||
| 334 | |||
| 335 | static 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 | |||
| 317 | void thread_stack__free(struct thread *thread) | 344 | void 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 | ||
