perf evlist: Support non overwrite mode in perf_evlist__read_on_cpu
authorArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 29 Jan 2011 11:08:13 +0000 (09:08 -0200)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sat, 29 Jan 2011 18:24:40 +0000 (16:24 -0200)
I.e. stash the overwrite mode in struct perf_evlist and act accordingly
in perf_evlist__read_on_cpu, not checking for overwrites and touching
the tail after consuming one event, like perf record does, for instance.

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c

index df0610e9c61b500284d5efb32761da91a9fa5847..b498eecbe8507ca59f943c7739345e787ab1c099 100644 (file)
@@ -116,24 +116,25 @@ event_t *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)
        unsigned int old = md->prev;
        unsigned char *data = md->base + page_size;
        event_t *event = NULL;
-       int diff;
-
-       /*
-        * If we're further behind than half the buffer, there's a chance
-        * 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.
-        *
-        * In either case, truncate and restart at head.
-        */
-       diff = head - old;
-       if (diff > md->mask / 2 || diff < 0) {
-               fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
 
+       if (evlist->overwrite) {
                /*
-                * head points to a known good entry, start there.
+                * If we're further behind than half the buffer, there's a chance
+                * 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.
+                *
+                * In either case, truncate and restart at head.
                 */
-               old = head;
+               int diff = head - old;
+               if (diff > md->mask / 2 || diff < 0) {
+                       fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
+
+                       /*
+                        * head points to a known good entry, start there.
+                        */
+                       old = head;
+               }
        }
 
        if (old != head) {
@@ -166,5 +167,9 @@ event_t *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu)
        }
 
        md->prev = old;
+
+       if (!evlist->overwrite)
+               perf_mmap__write_tail(md, old);
+
        return event;
 }
index acbe48eac6084879fae254d47d8860c75f9af334..2706ae40c8b38c91f9d8e97674b66439664c0606 100644 (file)
@@ -16,6 +16,7 @@ struct perf_evlist {
        int              nr_entries;
        int              nr_fds;
        int              mmap_len;
+       bool             overwrite;
        event_t          event_copy;
        struct perf_mmap *mmap;
        struct pollfd    *pollfd;
index 76ab553637d671fb89980eb9d5566c6854867934..f98b3e585039bbf926d8ea15fa01ab7b943387fe 100644 (file)
@@ -327,6 +327,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, struct cpu_map *cpus,
            perf_evlist__alloc_pollfd(evlist, cpus->nr, threads->nr) < 0)
                return -ENOMEM;
 
+       evlist->overwrite = overwrite;
        evlist->mmap_len = (pages + 1) * page_size;
        first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node);