@@ -325,19 +325,64 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
325
325
return symbol__tty_annotate2 (& he -> ms , evsel );
326
326
}
327
327
328
+ static void print_annotated_data_header (struct hist_entry * he , struct evsel * evsel )
329
+ {
330
+ struct dso * dso = map__dso (he -> ms .map );
331
+ int nr_members = 1 ;
332
+ int nr_samples = he -> stat .nr_events ;
333
+
334
+ if (evsel__is_group_event (evsel )) {
335
+ struct hist_entry * pair ;
336
+
337
+ list_for_each_entry (pair , & he -> pairs .head , pairs .node )
338
+ nr_samples += pair -> stat .nr_events ;
339
+ }
340
+
341
+ printf ("Annotate type: '%s' in %s (%d samples):\n" ,
342
+ he -> mem_type -> self .type_name , dso -> name , nr_samples );
343
+
344
+ if (evsel__is_group_event (evsel )) {
345
+ struct evsel * pos ;
346
+ int i = 0 ;
347
+
348
+ for_each_group_evsel (pos , evsel )
349
+ printf (" event[%d] = %s\n" , i ++ , pos -> name );
350
+
351
+ nr_members = evsel -> core .nr_members ;
352
+ }
353
+
354
+ printf ("============================================================================\n" );
355
+ printf ("%*s %10s %10s %s\n" , 11 * nr_members , "samples" , "offset" , "size" , "field" );
356
+ }
357
+
328
358
static void print_annotated_data_type (struct annotated_data_type * mem_type ,
329
359
struct annotated_member * member ,
330
360
struct evsel * evsel , int indent )
331
361
{
332
362
struct annotated_member * child ;
333
363
struct type_hist * h = mem_type -> histograms [evsel -> core .idx ];
334
- int i , samples = 0 ;
364
+ int i , nr_events = 1 , samples = 0 ;
335
365
336
366
for (i = 0 ; i < member -> size ; i ++ )
337
367
samples += h -> addr [member -> offset + i ].nr_samples ;
368
+ printf (" %10d" , samples );
369
+
370
+ if (evsel__is_group_event (evsel )) {
371
+ struct evsel * pos ;
372
+
373
+ for_each_group_member (pos , evsel ) {
374
+ h = mem_type -> histograms [pos -> core .idx ];
375
+
376
+ samples = 0 ;
377
+ for (i = 0 ; i < member -> size ; i ++ )
378
+ samples += h -> addr [member -> offset + i ].nr_samples ;
379
+ printf (" %10d" , samples );
380
+ }
381
+ nr_events = evsel -> core .nr_members ;
382
+ }
338
383
339
- printf (" %10d %10d %10d %*s%s\t%s" ,
340
- samples , member -> offset , member -> size , indent , "" , member -> type_name ,
384
+ printf (" %10d %10d %*s%s\t%s" ,
385
+ member -> offset , member -> size , indent , "" , member -> type_name ,
341
386
member -> var_name ?: "" );
342
387
343
388
if (!list_empty (& member -> children ))
@@ -347,7 +392,7 @@ static void print_annotated_data_type(struct annotated_data_type *mem_type,
347
392
print_annotated_data_type (mem_type , child , evsel , indent + 4 );
348
393
349
394
if (!list_empty (& member -> children ))
350
- printf ("%*s}" , 35 + indent , "" );
395
+ printf ("%*s}" , 11 * nr_events + 24 + indent , "" );
351
396
printf (";\n" );
352
397
}
353
398
@@ -391,8 +436,6 @@ static void hists__find_annotations(struct hists *hists,
391
436
}
392
437
393
438
if (ann -> data_type ) {
394
- struct dso * dso = map__dso (he -> ms .map );
395
-
396
439
/* skip unknown type */
397
440
if (he -> mem_type -> histograms == NULL )
398
441
goto find_next ;
@@ -414,11 +457,7 @@ static void hists__find_annotations(struct hists *hists,
414
457
goto find_next ;
415
458
}
416
459
417
- printf ("Annotate type: '%s' in %s (%d samples):\n" ,
418
- he -> mem_type -> self .type_name , dso -> name , he -> stat .nr_events );
419
- printf ("============================================================================\n" );
420
- printf (" %10s %10s %10s %s\n" , "samples" , "offset" , "size" , "field" );
421
-
460
+ print_annotated_data_header (he , evsel );
422
461
print_annotated_data_type (he -> mem_type , & he -> mem_type -> self , evsel , 0 );
423
462
printf ("\n" );
424
463
goto find_next ;
@@ -521,8 +560,20 @@ static int __cmd_annotate(struct perf_annotate *ann)
521
560
evsel__reset_sample_bit (pos , CALLCHAIN );
522
561
evsel__output_resort (pos , NULL );
523
562
524
- if (symbol_conf .event_group && !evsel__is_group_leader (pos ))
563
+ /*
564
+ * An event group needs to display other events too.
565
+ * Let's delay printing until other events are processed.
566
+ */
567
+ if (symbol_conf .event_group ) {
568
+ if (!evsel__is_group_leader (pos )) {
569
+ struct hists * leader_hists ;
570
+
571
+ leader_hists = evsel__hists (evsel__leader (pos ));
572
+ hists__match (leader_hists , hists );
573
+ hists__link (leader_hists , hists );
574
+ }
525
575
continue ;
576
+ }
526
577
527
578
hists__find_annotations (hists , pos , ann );
528
579
}
@@ -533,6 +584,20 @@ static int __cmd_annotate(struct perf_annotate *ann)
533
584
goto out ;
534
585
}
535
586
587
+ /* Display group events together */
588
+ evlist__for_each_entry (session -> evlist , pos ) {
589
+ struct hists * hists = evsel__hists (pos );
590
+ u32 nr_samples = hists -> stats .nr_samples ;
591
+
592
+ if (nr_samples == 0 )
593
+ continue ;
594
+
595
+ if (!symbol_conf .event_group || !evsel__is_group_leader (pos ))
596
+ continue ;
597
+
598
+ hists__find_annotations (hists , pos , ann );
599
+ }
600
+
536
601
if (use_browser == 2 ) {
537
602
void (* show_annotations )(void );
538
603
0 commit comments