It is desirable to be able to specify more than one group on
the command line.  This change adds the capability of specifying
multiple groups via multiple "-e <event>,<event>,.." switches.  Each
-e switch specifies a new group, and the events contained in that
group.  If grouping is not desired, the events can be placed in
individual -e switches, i.e. -e <event1> -e <event2> ...

Since this becomes the default behavior of "task", there is no
longer a need for the "-g" switch, and the need for the read_single()
function is eliminated.

This change simplifies the group leader handling and unifies the
logic so that grouping is always used... only the size and
number of groups varies.

Signed-off-by: Corey Ashford <cjash...@linux.vnet.ibm.com>
---
 perf_examples/perf_util.c |    7 +++-
 perf_examples/perf_util.h |    1 +
 perf_examples/task.c      |   88 +++++++++++++++++++-------------------------
 3 files changed, 44 insertions(+), 52 deletions(-)

diff --git a/perf_examples/perf_util.c b/perf_examples/perf_util.c
index 4de21a8..3853ddf 100644
--- a/perf_examples/perf_util.c
+++ b/perf_examples/perf_util.c
@@ -34,9 +34,11 @@
 int
 perf_setup_argv_events(char **argv, perf_event_desc_t **fd)
 {
-       perf_event_desc_t *fdt = NULL;
-       int num = 0, max_fd = 0, new_max;
+       static perf_event_desc_t *fdt = NULL;
+       static int num = 0, max_fd = 0;
+       int new_max;
        int ret;
+       const int group_leader = num;
 
        if (!(argv && fd))
                return -1;
@@ -72,6 +74,7 @@ perf_setup_argv_events(char **argv, perf_event_desc_t **fd)
                /* ABI compatibility */
                fdt[num].hw.size = sizeof(struct perf_event_attr);
                fdt[num].name = *argv;
+               fdt[num].group_leader = group_leader;
                num++;
                argv++;
        }
diff --git a/perf_examples/perf_util.h b/perf_examples/perf_util.h
index ae5449a..a6e1dc9 100644
--- a/perf_examples/perf_util.h
+++ b/perf_examples/perf_util.h
@@ -36,6 +36,7 @@ typedef struct {
        uint64_t id; /* event id kernel */
        void *buf;
        size_t pgmsk;
+       int group_leader;
        int fd;
 } perf_event_desc_t;
 
diff --git a/perf_examples/task.c b/perf_examples/task.c
index b29822a..aafd4bc 100644
--- a/perf_examples/task.c
+++ b/perf_examples/task.c
@@ -35,10 +35,12 @@
 
 #include "perf_util.h"
 
+#define MAX_GROUPS 16
+
 typedef struct {
-       const char *events;
+       const char *events[MAX_GROUPS];
+       int num_groups;
        int inherit;
-       int group;
        int print;
        int pin;
        pid_t pid;
@@ -107,36 +109,11 @@ read_group(perf_event_desc_t *fds, int num)
 }
 
 static void
-read_single(perf_event_desc_t *fds, int num)
-{
-       uint64_t values[3];
-       int i, ret;
-
-       for(i=0; i < num; i++) {
-
-               ret = read(fds[i].fd, values, sizeof(values));
-               if (ret != sizeof(values)) { /* unsigned */
-                       if (ret == -1)
-                               err(1, "cannot read values event %s", 
fds[i].name);
-                       else    /* likely pinned and could not be loaded */
-                               warnx("could not read event%d", i);
-               }
-               fds[i].prev_value = fds[i].value;
-               fds[i].value = perf_scale(values);
-               fds[i].enabled = values[1];
-               fds[i].running = values[2];
-       }
-}
-
-static void
 print_counts(perf_event_desc_t *fds, int num)
 {
        int i;
 
-       if (options.group)
-               read_group(fds, num);
-       else
-               read_single(fds, num);
+       read_group(fds, num);
 
        for(i=0; i < num; i++) {
                double ratio;
@@ -167,8 +144,8 @@ static void sig_handler(int n)
 int
 parent(char **arg)
 {
-       perf_event_desc_t *fds;
-       int status, ret, i, num;
+       perf_event_desc_t *fds = NULL;
+       int status, ret, i, num = 0, grp, group_fd;
        int ready[2], go[2];
        char buf;
        pid_t pid;
@@ -176,9 +153,11 @@ parent(char **arg)
        if (pfm_initialize() != PFM_SUCCESS)
                errx(1, "libpfm initialization failed");
 
-       num = perf_setup_list_events(options.events, &fds);
-       if (num < 1)
-               exit(1);
+       for (grp = 0; grp < options.num_groups; grp++) {
+               num = perf_setup_list_events(options.events[grp], &fds);
+               if (num < 1)
+                       exit(1);
+       }
 
        pid = options.pid;
        if (!pid) {
@@ -233,31 +212,37 @@ parent(char **arg)
 
        fds[0].fd = -1;
        for(i=0; i < num; i++) {
+               int is_group_leader; /* boolean */
+
+               if (fds[i].group_leader == i) {
+                       /* this is the group leader */
+                       group_fd = -1;
+                       is_group_leader = 1;
+               } else {
+                       group_fd = fds[fds[i].group_leader].fd;
+                       is_group_leader = 0;
+               }
+
                /*
                 * create leader disabled with enable_on-exec
                 */
                if (!options.pid) {
-                       if (options.group) {
-                               fds[i].hw.disabled = !i;
-                               fds[i].hw.enable_on_exec = !i;
-                       } else {
-                               fds[i].hw.disabled = 1;
-                               fds[i].hw.enable_on_exec = 1;
-                       }
+                       fds[i].hw.disabled = is_group_leader;
+                       fds[i].hw.enable_on_exec = is_group_leader;
                }
 
                fds[i].hw.read_format = PERF_FORMAT_SCALE;
                /* request timing information necessary for scaling counts */
-               if (!i && options.group)
+               if (is_group_leader)
                        fds[0].hw.read_format |= PERF_FORMAT_GROUP;
 
                if (options.inherit)
                        fds[i].hw.inherit = 1;
 
-               if (options.pin && ((options.group && i== 0) || 
(!options.group)))
+               if (options.pin && is_group_leader)
                        fds[i].hw.pinned = 1;
 
-               fds[i].fd = perf_event_open(&fds[i].hw, pid, -1, options.group 
? fds[0].fd : -1, 0);
+               fds[i].fd = perf_event_open(&fds[i].hw, pid, -1, group_fd, 0);
                if (fds[i].fd == -1) {
                        warn("cannot attach event%d %s", i, fds[i].name);
                        goto error;
@@ -323,10 +308,12 @@ main(int argc, char **argv)
        while ((c=getopt(argc, argv,"he:igpPt:")) != -1) {
                switch(c) {
                        case 'e':
-                               options.events = optarg;
-                               break;
-                       case 'g':
-                               options.group = 1;
+                               if (options.num_groups < MAX_GROUPS) {
+                                       options.events[options.num_groups++] = 
optarg;
+                               } else {
+                                       errx(1, "you cannot specify more than 
%d groups.\n",
+                                               MAX_GROUPS);
+                               }
                                break;
                        case 'p':
                                options.print = 1;
@@ -347,9 +334,10 @@ main(int argc, char **argv)
                                errx(1, "unknown error");
                }
        }
-       if (!options.events)
-               options.events = 
"PERF_COUNT_HW_CPU_CYCLES,PERF_COUNT_HW_INSTRUCTIONS";
-
+       if (!options.events) {
+               options.events[0] = 
"PERF_COUNT_HW_CPU_CYCLES,PERF_COUNT_HW_INSTRUCTIONS";
+               options.num_groups = 1;
+       }
        if (!argv[optind] && !options.pid)
                errx(1, "you must specify a command to execute or a thread to 
attach to\n");
        
-- 
1.7.0.4


------------------------------------------------------------------------------
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to