Simple thread counting-group with counter-multiplexing and multi-mode example

The following example has two threads in a counting-group. The body of the auxiliary thread's initialization routine is the same as in the previous example.

This example is similar to the previous one except that it uses the multi-mode functionality, and associates a mode with each group counted.

main()
{
        pm_info2_t         pminfo; 
        pm_groups_info_t   pmginfo;
        pm_prog_mm_t       prog;
        pm_data_mx_t       data;
        pm_prog_t          prog_set[2];
        int filter = PM_VERIFIED;  /* get list of verified events */
        pm_initialize(filter, &pminfo, &pmginfo, PM_CURRENT );
        prog.prog_set = prog_set;
        prog.nb_set_prog   = 2;      /* two groups counted */
        prog.slice_duration   = 200; /* slice duration for each event group is 200ms */
        prog_set[0].mode.w           = 0;  /* start with clean mode */
        prog_set[0].mode.b.user      = 1;  /* grp 0: count only user mode */
        prog_set[0].mode.b.is_group  = 1;  /* specify event group */
        prog_set[0].mode.b.proctree  = 1;  /* turns process tree counting on:
                                              this option is common to all counted groups */
        prog_set[1].mode.w           = 0;  /* start with clean mode */
        prog_set[1].mode.b.kernel    = 1;  /* grp 1: count only kernel mode */
        prog_set[1].mode.b.is_group  = 1;  /* specify event group */
        for (i = 0; i < pminfo.maxpmcs; i++) {
                prog_set[0].events[i] = COUNT_NOTHING;
                prog_set[1].events[i] = COUNT_NOTHING;
        }
        prog_set[0].events[0]     = 1;   /* count events in group 1 in the first set */
        prog_set[1].events[0]     = 3;   /* count events in group 3 in the first set */
        pm_set_program_mygroup_mm(&prog); /* create counting group */
        pm_start_mygroup();
        pthread_create(&threadid, &attr, doit, NULL);
        pm_start_mythread();
        ... usefull work ....
        pm_stop_mythread();
        pm_get_data_mythread_mx(&data);
        printf ("Main thread results:\n");
        for (i = 0; i < 2 ; i++) {
                group_number = prog_set[i].events[0];
                printf ("Group #%d: %s\n", group_number, pmginfo.event_groups[group_number].short_name);
                printf ("    counting time: %d ms\n", data.accu_set[i].accu_time);
                printf ("    counting values:\n");
                for (counter = 0; counter < pminfo.maxpmcs; counter++) {
                        printf ("event %d: %d\n", counter, data.accu_set[i].accu_data[counter]);
                }
        }
  (1)   free(data.accu_set);   /* free the memory allocated for the main thread results */
        pthread_join(threadid, &status);
        ... print auxiliary thread results ...
        free(data.accu_set);   /* free the memory allocated for the thread results */
        pm_get_data_mygroup_mx(&data)
        ... print group results ...
        free(data.accu_set);   /* free the memory allocated for the group results */
        pm_delete_program();
}
(1) Each time data are got in time slice mode, the buffer allocated to return the 
counters must be freed after used.
}