diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-10-23 02:23:20 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-10-23 02:23:20 -0400 |
| commit | 43315956509ca6913764861ac7dec128b91eb1ec (patch) | |
| tree | 60fd5647f150a46e63093a41417c2eef3e776b3d /tools/perf/util/header.c | |
| parent | 9bf4e7fba8006d19846fec877b6da0616b2772de (diff) | |
| parent | 6beba7adbe092e63dfe8d09fbd1e3ec140474a13 (diff) | |
Merge branch 'perf/core' into perf/probes
Conflicts:
tools/perf/Makefile
Merge reason:
- fix the conflict
- pick up the pr_*() infrastructure to queue up dependent patch
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/header.c')
| -rw-r--r-- | tools/perf/util/header.c | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index e306857b2c2b..7d26659b806c 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | #include "util.h" | 6 | #include "util.h" |
| 7 | #include "header.h" | 7 | #include "header.h" |
| 8 | #include "../perf.h" | ||
| 9 | #include "trace-event.h" | ||
| 8 | 10 | ||
| 9 | /* | 11 | /* |
| 10 | * Create new perf.data header attribute: | 12 | * Create new perf.data header attribute: |
| @@ -46,23 +48,17 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id) | |||
| 46 | */ | 48 | */ |
| 47 | struct perf_header *perf_header__new(void) | 49 | struct perf_header *perf_header__new(void) |
| 48 | { | 50 | { |
| 49 | struct perf_header *self = malloc(sizeof(*self)); | 51 | struct perf_header *self = calloc(sizeof(*self), 1); |
| 50 | 52 | ||
| 51 | if (!self) | 53 | if (!self) |
| 52 | die("nomem"); | 54 | die("nomem"); |
| 53 | 55 | ||
| 54 | self->frozen = 0; | ||
| 55 | |||
| 56 | self->attrs = 0; | ||
| 57 | self->size = 1; | 56 | self->size = 1; |
| 58 | self->attr = malloc(sizeof(void *)); | 57 | self->attr = malloc(sizeof(void *)); |
| 59 | 58 | ||
| 60 | if (!self->attr) | 59 | if (!self->attr) |
| 61 | die("nomem"); | 60 | die("nomem"); |
| 62 | 61 | ||
| 63 | self->data_offset = 0; | ||
| 64 | self->data_size = 0; | ||
| 65 | |||
| 66 | return self; | 62 | return self; |
| 67 | } | 63 | } |
| 68 | 64 | ||
| @@ -97,7 +93,7 @@ static struct perf_trace_event_type *events; | |||
| 97 | void perf_header__push_event(u64 id, const char *name) | 93 | void perf_header__push_event(u64 id, const char *name) |
| 98 | { | 94 | { |
| 99 | if (strlen(name) > MAX_EVENT_NAME) | 95 | if (strlen(name) > MAX_EVENT_NAME) |
| 100 | printf("Event %s will be truncated\n", name); | 96 | pr_warning("Event %s will be truncated\n", name); |
| 101 | 97 | ||
| 102 | if (!events) { | 98 | if (!events) { |
| 103 | events = malloc(sizeof(struct perf_trace_event_type)); | 99 | events = malloc(sizeof(struct perf_trace_event_type)); |
| @@ -145,8 +141,14 @@ struct perf_file_header { | |||
| 145 | struct perf_file_section attrs; | 141 | struct perf_file_section attrs; |
| 146 | struct perf_file_section data; | 142 | struct perf_file_section data; |
| 147 | struct perf_file_section event_types; | 143 | struct perf_file_section event_types; |
| 144 | DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS); | ||
| 148 | }; | 145 | }; |
| 149 | 146 | ||
| 147 | void perf_header__feat_trace_info(struct perf_header *header) | ||
| 148 | { | ||
| 149 | set_bit(HEADER_TRACE_INFO, header->adds_features); | ||
| 150 | } | ||
| 151 | |||
| 150 | static void do_write(int fd, void *buf, size_t size) | 152 | static void do_write(int fd, void *buf, size_t size) |
| 151 | { | 153 | { |
| 152 | while (size) { | 154 | while (size) { |
| @@ -160,6 +162,32 @@ static void do_write(int fd, void *buf, size_t size) | |||
| 160 | } | 162 | } |
| 161 | } | 163 | } |
| 162 | 164 | ||
| 165 | static void perf_header__adds_write(struct perf_header *self, int fd) | ||
| 166 | { | ||
| 167 | struct perf_file_section trace_sec; | ||
| 168 | u64 cur_offset = lseek(fd, 0, SEEK_CUR); | ||
| 169 | unsigned long *feat_mask = self->adds_features; | ||
| 170 | |||
| 171 | if (test_bit(HEADER_TRACE_INFO, feat_mask)) { | ||
| 172 | /* Write trace info */ | ||
| 173 | trace_sec.offset = lseek(fd, sizeof(trace_sec), SEEK_CUR); | ||
| 174 | read_tracing_data(fd, attrs, nr_counters); | ||
| 175 | trace_sec.size = lseek(fd, 0, SEEK_CUR) - trace_sec.offset; | ||
| 176 | |||
| 177 | /* Write trace info headers */ | ||
| 178 | lseek(fd, cur_offset, SEEK_SET); | ||
| 179 | do_write(fd, &trace_sec, sizeof(trace_sec)); | ||
| 180 | |||
| 181 | /* | ||
| 182 | * Update cur_offset. So that other (future) | ||
| 183 | * features can set their own infos in this place. But if we are | ||
| 184 | * the only feature, at least that seeks to the place the data | ||
| 185 | * should begin. | ||
| 186 | */ | ||
| 187 | cur_offset = lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET); | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | |||
| 163 | void perf_header__write(struct perf_header *self, int fd) | 191 | void perf_header__write(struct perf_header *self, int fd) |
| 164 | { | 192 | { |
| 165 | struct perf_file_header f_header; | 193 | struct perf_file_header f_header; |
| @@ -198,6 +226,7 @@ void perf_header__write(struct perf_header *self, int fd) | |||
| 198 | if (events) | 226 | if (events) |
| 199 | do_write(fd, events, self->event_size); | 227 | do_write(fd, events, self->event_size); |
| 200 | 228 | ||
| 229 | perf_header__adds_write(self, fd); | ||
| 201 | 230 | ||
| 202 | self->data_offset = lseek(fd, 0, SEEK_CUR); | 231 | self->data_offset = lseek(fd, 0, SEEK_CUR); |
| 203 | 232 | ||
| @@ -219,6 +248,8 @@ void perf_header__write(struct perf_header *self, int fd) | |||
| 219 | }, | 248 | }, |
| 220 | }; | 249 | }; |
| 221 | 250 | ||
| 251 | memcpy(&f_header.adds_features, &self->adds_features, sizeof(self->adds_features)); | ||
| 252 | |||
| 222 | lseek(fd, 0, SEEK_SET); | 253 | lseek(fd, 0, SEEK_SET); |
| 223 | do_write(fd, &f_header, sizeof(f_header)); | 254 | do_write(fd, &f_header, sizeof(f_header)); |
| 224 | lseek(fd, self->data_offset + self->data_size, SEEK_SET); | 255 | lseek(fd, self->data_offset + self->data_size, SEEK_SET); |
| @@ -241,6 +272,20 @@ static void do_read(int fd, void *buf, size_t size) | |||
| 241 | } | 272 | } |
| 242 | } | 273 | } |
| 243 | 274 | ||
| 275 | static void perf_header__adds_read(struct perf_header *self, int fd) | ||
| 276 | { | ||
| 277 | const unsigned long *feat_mask = self->adds_features; | ||
| 278 | |||
| 279 | if (test_bit(HEADER_TRACE_INFO, feat_mask)) { | ||
| 280 | struct perf_file_section trace_sec; | ||
| 281 | |||
| 282 | do_read(fd, &trace_sec, sizeof(trace_sec)); | ||
| 283 | lseek(fd, trace_sec.offset, SEEK_SET); | ||
| 284 | trace_report(fd); | ||
| 285 | lseek(fd, trace_sec.offset + trace_sec.size, SEEK_SET); | ||
| 286 | } | ||
| 287 | }; | ||
| 288 | |||
| 244 | struct perf_header *perf_header__read(int fd) | 289 | struct perf_header *perf_header__read(int fd) |
| 245 | { | 290 | { |
| 246 | struct perf_header *self = perf_header__new(); | 291 | struct perf_header *self = perf_header__new(); |
| @@ -254,10 +299,16 @@ struct perf_header *perf_header__read(int fd) | |||
| 254 | do_read(fd, &f_header, sizeof(f_header)); | 299 | do_read(fd, &f_header, sizeof(f_header)); |
| 255 | 300 | ||
| 256 | if (f_header.magic != PERF_MAGIC || | 301 | if (f_header.magic != PERF_MAGIC || |
| 257 | f_header.size != sizeof(f_header) || | ||
| 258 | f_header.attr_size != sizeof(f_attr)) | 302 | f_header.attr_size != sizeof(f_attr)) |
| 259 | die("incompatible file format"); | 303 | die("incompatible file format"); |
| 260 | 304 | ||
| 305 | if (f_header.size != sizeof(f_header)) { | ||
| 306 | /* Support the previous format */ | ||
| 307 | if (f_header.size == offsetof(typeof(f_header), adds_features)) | ||
| 308 | bitmap_zero(f_header.adds_features, HEADER_FEAT_BITS); | ||
| 309 | else | ||
| 310 | die("incompatible file format"); | ||
| 311 | } | ||
| 261 | nr_attrs = f_header.attrs.size / sizeof(f_attr); | 312 | nr_attrs = f_header.attrs.size / sizeof(f_attr); |
| 262 | lseek(fd, f_header.attrs.offset, SEEK_SET); | 313 | lseek(fd, f_header.attrs.offset, SEEK_SET); |
| 263 | 314 | ||
| @@ -290,6 +341,11 @@ struct perf_header *perf_header__read(int fd) | |||
| 290 | do_read(fd, events, f_header.event_types.size); | 341 | do_read(fd, events, f_header.event_types.size); |
| 291 | event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); | 342 | event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); |
| 292 | } | 343 | } |
| 344 | |||
| 345 | memcpy(&self->adds_features, &f_header.adds_features, sizeof(f_header.adds_features)); | ||
| 346 | |||
| 347 | perf_header__adds_read(self, fd); | ||
| 348 | |||
| 293 | self->event_offset = f_header.event_types.offset; | 349 | self->event_offset = f_header.event_types.offset; |
| 294 | self->event_size = f_header.event_types.size; | 350 | self->event_size = f_header.event_types.size; |
| 295 | 351 | ||
