diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-15 07:40:59 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-22 16:56:30 -0500 |
commit | 04391debc3e1195222a4dbb162ace6542dd89c1c (patch) | |
tree | 910f12bd4d1f08c37d2086b4c725f50a8dd3c682 /tools/perf/builtin-top.c | |
parent | 98d77b78504a423fca911a26a17bee00ef2fdda2 (diff) |
perf evlist: Steal mmap reading routine from 'perf top'
Will be used in the upcoming 'perf test' entry for the evlist mmap
routines.
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>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 56 |
1 files changed, 3 insertions, 53 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index df85c1f9417b..58352ad807c7 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -1100,67 +1100,17 @@ static void event__process_sample(const event_t *self, | |||
1100 | 1100 | ||
1101 | static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu) | 1101 | static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu) |
1102 | { | 1102 | { |
1103 | struct perf_mmap *md = &evsel_list->mmap[cpu]; | ||
1104 | unsigned int head = perf_mmap__read_head(md); | ||
1105 | unsigned int old = md->prev; | ||
1106 | unsigned char *data = md->base + page_size; | ||
1107 | struct sample_data sample; | 1103 | struct sample_data sample; |
1108 | int diff; | 1104 | event_t *event; |
1109 | |||
1110 | /* | ||
1111 | * If we're further behind than half the buffer, there's a chance | ||
1112 | * the writer will bite our tail and mess up the samples under us. | ||
1113 | * | ||
1114 | * If we somehow ended up ahead of the head, we got messed up. | ||
1115 | * | ||
1116 | * In either case, truncate and restart at head. | ||
1117 | */ | ||
1118 | diff = head - old; | ||
1119 | if (diff > md->mask / 2 || diff < 0) { | ||
1120 | fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); | ||
1121 | |||
1122 | /* | ||
1123 | * head points to a known good entry, start there. | ||
1124 | */ | ||
1125 | old = head; | ||
1126 | } | ||
1127 | |||
1128 | for (; old != head;) { | ||
1129 | event_t *event = (event_t *)&data[old & md->mask]; | ||
1130 | |||
1131 | event_t event_copy; | ||
1132 | |||
1133 | size_t size = event->header.size; | ||
1134 | |||
1135 | /* | ||
1136 | * Event straddles the mmap boundary -- header should always | ||
1137 | * be inside due to u64 alignment of output. | ||
1138 | */ | ||
1139 | if ((old & md->mask) + size != ((old + size) & md->mask)) { | ||
1140 | unsigned int offset = old; | ||
1141 | unsigned int len = min(sizeof(*event), size), cpy; | ||
1142 | void *dst = &event_copy; | ||
1143 | |||
1144 | do { | ||
1145 | cpy = min(md->mask + 1 - (offset & md->mask), len); | ||
1146 | memcpy(dst, &data[offset & md->mask], cpy); | ||
1147 | offset += cpy; | ||
1148 | dst += cpy; | ||
1149 | len -= cpy; | ||
1150 | } while (len); | ||
1151 | |||
1152 | event = &event_copy; | ||
1153 | } | ||
1154 | 1105 | ||
1106 | while ((event = perf_evlist__read_on_cpu(evsel_list, cpu)) != NULL) { | ||
1155 | event__parse_sample(event, self, &sample); | 1107 | event__parse_sample(event, self, &sample); |
1108 | |||
1156 | if (event->header.type == PERF_RECORD_SAMPLE) | 1109 | if (event->header.type == PERF_RECORD_SAMPLE) |
1157 | event__process_sample(event, &sample, self); | 1110 | event__process_sample(event, &sample, self); |
1158 | else | 1111 | else |
1159 | event__process(event, &sample, self); | 1112 | event__process(event, &sample, self); |
1160 | old += size; | ||
1161 | } | 1113 | } |
1162 | |||
1163 | md->prev = old; | ||
1164 | } | 1114 | } |
1165 | 1115 | ||
1166 | static void perf_session__mmap_read(struct perf_session *self) | 1116 | static void perf_session__mmap_read(struct perf_session *self) |