Simple thread counting-group with counter-multiplexing 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.

main()
{
        pm_info2_t         pminfo;
        pm_groups_info_t   pmginfo;
        pm_prog_mx_r       prog;
        pm_events_prog_t   event_set[2];
        pm_data_mx_t       data;
        int filter = PM_VERIFIED;  /* get list of verified events */
        pm_initialize(filter, &pminfo, &pmginfo, PM_CURRENT )
        prog.mode.w           = 0;  /* start with clean mode */
        prog.mode.b.user      = 1;  /* count only user mode */
        prog.mode.b.is_group  = 1;  /* specify event group */
        prog.events_set       = event_set;
        prog.nb_events_prog   = 2;   /* two event group counted */
        prog.slice_duration   = 200; /* slice duration for each event group is 200ms */
        for (i = 0; i < pminfo.maxpmcs; i++) {
                event_set[0][i] = COUNT_NOTHING;
                event_set[1][i] = COUNT_NOTHING;
        }

        event_set[0][0]     = 1;   /* count events in group 1 in the first set */
        event_set[1][0]     = 3;   /* count events in group 3 in the first set */
        pm_set_program_mygroup_mx(&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 = event_set[i][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 alloacted 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 memoory 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.