aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
authorTom Zanussi <tzanussi@gmail.com>2010-04-02 00:59:19 -0400
committerIngo Molnar <mingo@elte.hu>2010-04-14 05:56:07 -0400
commit2c46dbb517a10b18d459e6ceffefde5bfb290cf6 (patch)
tree20853decc73cd1fc69c2db7d8227d11cce6ee4de /tools/perf/util/header.c
parentc239da3b4b55dbb8f30bcb8d1a0d63fc44a567c3 (diff)
perf: Convert perf header attrs into attr events
Bypasses the attr perf header code and replaces it with a synthesized event and processing function that accomplishes the same thing, used when reading/writing perf data to/from a pipe. Making the attrs into events allows them to be streamed over a pipe along with the rest of the header data (in later patches). It also paves the way to allowing events to be added and removed from perf sessions dynamically. Signed-off-by: Tom Zanussi <tzanussi@gmail.com> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: fweisbec@gmail.com Cc: rostedt@goodmis.org Cc: k-keiichi@bx.jp.nec.com Cc: acme@ghostprotocols.net LKML-Reference: <1270184365-8281-6-git-send-email-tzanussi@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 8d05337d1a59..e36173934e8b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -807,3 +807,82 @@ perf_header__find_attr(u64 id, struct perf_header *header)
807 807
808 return NULL; 808 return NULL;
809} 809}
810
811int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
812 event__handler_t process,
813 struct perf_session *session)
814{
815 event_t *ev;
816 size_t size;
817 int err;
818
819 size = sizeof(struct perf_event_attr);
820 size = ALIGN(size, sizeof(u64));
821 size += sizeof(struct perf_event_header);
822 size += ids * sizeof(u64);
823
824 ev = malloc(size);
825
826 ev->attr.attr = *attr;
827 memcpy(ev->attr.id, id, ids * sizeof(u64));
828
829 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
830 ev->attr.header.size = size;
831
832 err = process(ev, session);
833
834 free(ev);
835
836 return err;
837}
838
839int event__synthesize_attrs(struct perf_header *self,
840 event__handler_t process,
841 struct perf_session *session)
842{
843 struct perf_header_attr *attr;
844 int i, err = 0;
845
846 for (i = 0; i < self->attrs; i++) {
847 attr = self->attr[i];
848
849 err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
850 process, session);
851 if (err) {
852 pr_debug("failed to create perf header attribute\n");
853 return err;
854 }
855 }
856
857 return err;
858}
859
860int event__process_attr(event_t *self, struct perf_session *session)
861{
862 struct perf_header_attr *attr;
863 unsigned int i, ids, n_ids;
864
865 attr = perf_header_attr__new(&self->attr.attr);
866 if (attr == NULL)
867 return -ENOMEM;
868
869 ids = self->header.size;
870 ids -= (void *)&self->attr.id - (void *)self;
871 n_ids = ids / sizeof(u64);
872
873 for (i = 0; i < n_ids; i++) {
874 if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
875 perf_header_attr__delete(attr);
876 return -ENOMEM;
877 }
878 }
879
880 if (perf_header__add_attr(&session->header, attr) < 0) {
881 perf_header_attr__delete(attr);
882 return -ENOMEM;
883 }
884
885 perf_session__update_sample_type(session);
886
887 return 0;
888}