perf: Convert perf header attrs into attr events
[deliverable/linux.git] / tools / perf / util / header.c
index 8d05337d1a5913578a81355f9e8f20d76880d0e1..e36173934e8b36d14d2e64506f7aafdac017c818 100644 (file)
@@ -807,3 +807,82 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 
        return NULL;
 }
+
+int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
+                          event__handler_t process,
+                          struct perf_session *session)
+{
+       event_t *ev;
+       size_t size;
+       int err;
+
+       size = sizeof(struct perf_event_attr);
+       size = ALIGN(size, sizeof(u64));
+       size += sizeof(struct perf_event_header);
+       size += ids * sizeof(u64);
+
+       ev = malloc(size);
+
+       ev->attr.attr = *attr;
+       memcpy(ev->attr.id, id, ids * sizeof(u64));
+
+       ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
+       ev->attr.header.size = size;
+
+       err = process(ev, session);
+
+       free(ev);
+
+       return err;
+}
+
+int event__synthesize_attrs(struct perf_header *self,
+                           event__handler_t process,
+                           struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       int i, err = 0;
+
+       for (i = 0; i < self->attrs; i++) {
+               attr = self->attr[i];
+
+               err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
+                                            process, session);
+               if (err) {
+                       pr_debug("failed to create perf header attribute\n");
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+int event__process_attr(event_t *self, struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       unsigned int i, ids, n_ids;
+
+       attr = perf_header_attr__new(&self->attr.attr);
+       if (attr == NULL)
+               return -ENOMEM;
+
+       ids = self->header.size;
+       ids -= (void *)&self->attr.id - (void *)self;
+       n_ids = ids / sizeof(u64);
+
+       for (i = 0; i < n_ids; i++) {
+               if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
+                       perf_header_attr__delete(attr);
+                       return -ENOMEM;
+               }
+       }
+
+       if (perf_header__add_attr(&session->header, attr) < 0) {
+               perf_header_attr__delete(attr);
+               return -ENOMEM;
+       }
+
+       perf_session__update_sample_type(session);
+
+       return 0;
+}
This page took 0.050608 seconds and 5 git commands to generate.