]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - Documentation/perf_counter/builtin-record.c
perf_counter tools: Sample and display frequency adjustment changes
[mv-sheeva.git] / Documentation / perf_counter / builtin-record.c
index efa2eb498e9cd00b9a83f207491ebcfa4405bff1..43ddab31ac399c894e27fdf3bb057ad7f7d3ed55 100644 (file)
@@ -27,6 +27,7 @@ static int                    fd[MAX_NR_CPUS][MAX_COUNTERS];
 static int                     nr_cpus                         = 0;
 static unsigned int            page_size;
 static unsigned int            mmap_pages                      = 128;
+static int                     freq                            = 0;
 static int                     output;
 static const char              *output_name                    = "perf.data";
 static int                     group                           = 0;
@@ -64,7 +65,7 @@ static unsigned int mmap_read_head(struct mmap_data *md)
        return head;
 }
 
-static long events;
+static long samples;
 static struct timeval last_read, this_read;
 
 static __u64 bytes_written;
@@ -82,7 +83,7 @@ static void mmap_read(struct mmap_data *md)
 
        /*
         * If we're further behind than half the buffer, there's a chance
-        * the writer will bite our tail and screw up the events under us.
+        * the writer will bite our tail and mess up the samples under us.
         *
         * If we somehow ended up ahead of the head, we got messed up.
         *
@@ -108,7 +109,7 @@ static void mmap_read(struct mmap_data *md)
        last_read = this_read;
 
        if (old != head)
-               events++;
+               samples++;
 
        size = head - old;
 
@@ -256,7 +257,7 @@ out_failure:
        exit(EXIT_FAILURE);
 }
 
-static void pid_synthesize_mmap_events(pid_t pid)
+static void pid_synthesize_mmap_samples(pid_t pid)
 {
        char filename[PATH_MAX];
        FILE *fp;
@@ -314,7 +315,7 @@ static void pid_synthesize_mmap_events(pid_t pid)
        fclose(fp);
 }
 
-static void synthesize_events(void)
+static void synthesize_samples(void)
 {
        DIR *proc;
        struct dirent dirent, *next;
@@ -330,71 +331,78 @@ static void synthesize_events(void)
                        continue;
 
                pid_synthesize_comm_event(pid, 1);
-               pid_synthesize_mmap_events(pid);
+               pid_synthesize_mmap_samples(pid);
        }
 
        closedir(proc);
 }
 
-static void open_counters(int cpu, pid_t pid)
+static int group_fd;
+
+static void create_counter(int counter, int cpu, pid_t pid)
 {
        struct perf_counter_attr attr;
-       int counter, group_fd;
        int track = 1;
 
-       if (pid > 0) {
-               pid_synthesize_comm_event(pid, 0);
-               pid_synthesize_mmap_events(pid);
-       }
+       memset(&attr, 0, sizeof(attr));
+       attr.config             = event_id[counter];
+       attr.sample_period      = event_count[counter];
+       attr.sample_type        = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_PERIOD;
+       attr.freq               = freq;
+       attr.mmap               = track;
+       attr.comm               = track;
+       attr.inherit            = (cpu < 0) && inherit;
 
-       group_fd = -1;
-       for (counter = 0; counter < nr_counters; counter++) {
+       track = 0; /* only the first counter needs these */
 
-               memset(&attr, 0, sizeof(attr));
-               attr.config             = event_id[counter];
-               attr.sample_period      = event_count[counter];
-               attr.sample_type        = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
-               attr.mmap               = track;
-               attr.comm               = track;
-               attr.inherit    = (cpu < 0) && inherit;
+       fd[nr_cpu][counter] = sys_perf_counter_open(&attr, pid, cpu, group_fd, 0);
 
-               track = 0; // only the first counter needs these
+       if (fd[nr_cpu][counter] < 0) {
+               int err = errno;
 
-               fd[nr_cpu][counter] =
-                       sys_perf_counter_open(&attr, pid, cpu, group_fd, 0);
+               error("syscall returned with %d (%s)\n",
+                               fd[nr_cpu][counter], strerror(err));
+               if (err == EPERM)
+                       printf("Are you root?\n");
+               exit(-1);
+       }
+       assert(fd[nr_cpu][counter] >= 0);
+       fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
 
-               if (fd[nr_cpu][counter] < 0) {
-                       int err = errno;
+       /*
+        * First counter acts as the group leader:
+        */
+       if (group && group_fd == -1)
+               group_fd = fd[nr_cpu][counter];
+
+       event_array[nr_poll].fd = fd[nr_cpu][counter];
+       event_array[nr_poll].events = POLLIN;
+       nr_poll++;
+
+       mmap_array[nr_cpu][counter].counter = counter;
+       mmap_array[nr_cpu][counter].prev = 0;
+       mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
+       mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
+                       PROT_READ, MAP_SHARED, fd[nr_cpu][counter], 0);
+       if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
+               error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+               exit(-1);
+       }
+}
 
-                       error("syscall returned with %d (%s)\n",
-                                       fd[nr_cpu][counter], strerror(err));
-                       if (err == EPERM)
-                               printf("Are you root?\n");
-                       exit(-1);
-               }
-               assert(fd[nr_cpu][counter] >= 0);
-               fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
+static void open_counters(int cpu, pid_t pid)
+{
+       int counter;
 
-               /*
-                * First counter acts as the group leader:
-                */
-               if (group && group_fd == -1)
-                       group_fd = fd[nr_cpu][counter];
-
-               event_array[nr_poll].fd = fd[nr_cpu][counter];
-               event_array[nr_poll].events = POLLIN;
-               nr_poll++;
-
-               mmap_array[nr_cpu][counter].counter = counter;
-               mmap_array[nr_cpu][counter].prev = 0;
-               mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
-               mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                               PROT_READ, MAP_SHARED, fd[nr_cpu][counter], 0);
-               if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
-                       error("failed to mmap with %d (%s)\n", errno, strerror(errno));
-                       exit(-1);
-               }
+       if (pid > 0) {
+               pid_synthesize_comm_event(pid, 0);
+               pid_synthesize_mmap_samples(pid);
        }
+
+       group_fd = -1;
+       for (counter = 0; counter < nr_counters; counter++)
+               create_counter(counter, cpu, pid);
+
        nr_cpu++;
 }
 
@@ -430,7 +438,7 @@ static int __cmd_record(int argc, const char **argv)
        }
 
        if (!system_wide) {
-               open_counters(-1, target_pid != -1 ? target_pid : 0);
+               open_counters(-1, target_pid != -1 ? target_pid : getpid());
        } else for (i = 0; i < nr_cpus; i++)
                open_counters(i, target_pid);
 
@@ -461,17 +469,17 @@ static int __cmd_record(int argc, const char **argv)
        }
 
        if (system_wide)
-               synthesize_events();
+               synthesize_samples();
 
        while (!done) {
-               int hits = events;
+               int hits = samples;
 
                for (i = 0; i < nr_cpu; i++) {
                        for (counter = 0; counter < nr_counters; counter++)
                                mmap_read(&mmap_array[i][counter]);
                }
 
-               if (hits == events)
+               if (hits == samples)
                        ret = poll(event_array, nr_poll, 100);
        }
 
@@ -479,7 +487,7 @@ static int __cmd_record(int argc, const char **argv)
         * Approximate RIP event size: 24 bytes.
         */
        fprintf(stderr,
-               "[ perf record: Captured and wrote %.3f MB %s (~%lld events) ]\n",
+               "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n",
                (double)bytes_written / 1024.0 / 1024.0,
                output_name,
                bytes_written / 24);
@@ -514,6 +522,8 @@ static const struct option options[] = {
                    "output file name"),
        OPT_BOOLEAN('i', "inherit", &inherit,
                    "child tasks inherit counters"),
+       OPT_INTEGER('F', "freq", &freq,
+                   "profile at this frequency"),
        OPT_INTEGER('m', "mmap-pages", &mmap_pages,
                    "number of mmap data pages"),
        OPT_END()
@@ -534,6 +544,10 @@ int cmd_record(int argc, const char **argv, const char *prefix)
                event_id[0] = 0;
        }
 
+       if (freq) {
+               default_interval = freq;
+               freq = 1;
+       }
        for (counter = 0; counter < nr_counters; counter++) {
                if (event_count[counter])
                        continue;