summaryrefslogtreecommitdiffstats
path: root/lib/libpmc
diff options
context:
space:
mode:
authorjkoshy <jkoshy@FreeBSD.org>2007-12-03 11:15:46 +0000
committerjkoshy <jkoshy@FreeBSD.org>2007-12-03 11:15:46 +0000
commit86277bac23504de54f439ce27b121d2c24eac93d (patch)
treefa662372ed61770224589cebfe2f44a82eed8b2b /lib/libpmc
parent8304a663db3ad44c1f9590aedd446c2f1360dd54 (diff)
downloadFreeBSD-src-86277bac23504de54f439ce27b121d2c24eac93d.zip
FreeBSD-src-86277bac23504de54f439ce27b121d2c24eac93d.tar.gz
Add callchain parsing to -lpmc.
Sponsored by: FreeBSD Foundation and Google Inc.
Diffstat (limited to 'lib/libpmc')
-rw-r--r--lib/libpmc/pmclog.c25
-rw-r--r--lib/libpmc/pmclog.h15
2 files changed, 36 insertions, 4 deletions
diff --git a/lib/libpmc/pmclog.c b/lib/libpmc/pmclog.c
index fcd4a4f..ab054a5 100644
--- a/lib/libpmc/pmclog.c
+++ b/lib/libpmc/pmclog.c
@@ -1,7 +1,11 @@
/*-
- * Copyright (c) 2005-2006 Joseph Koshy
+ * Copyright (c) 2005-2007 Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -270,7 +274,7 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len,
struct pmclog_ev *ev)
{
int evlen, pathlen;
- uint32_t h, *le;
+ uint32_t h, *le, npc;
enum pmclog_parser_state e;
struct pmclog_parse_state *ps;
@@ -310,7 +314,22 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len,
goto error; \
} while (0)
+#define PMCLOG_GET_CALLCHAIN_SIZE(SZ,E) do { \
+ (SZ) = ((E) - offsetof(struct pmclog_callchain, pl_pc)) \
+ / sizeof(uintfptr_t); \
+ } while (0);
+
switch (ev->pl_type = PMCLOG_HEADER_TO_TYPE(h)) {
+ case PMCLOG_TYPE_CALLCHAIN:
+ PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_pid);
+ PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_pmcid);
+ PMCLOG_READ32(le,ev->pl_u.pl_cc.pl_cpuflags);
+ PMCLOG_GET_CALLCHAIN_SIZE(ev->pl_u.pl_cc.pl_npc,evlen);
+ for (npc = 0; npc < ev->pl_u.pl_cc.pl_npc; npc++)
+ PMCLOG_READADDR(le,ev->pl_u.pl_cc.pl_pc[npc]);
+ for (;npc < PMC_CALLCHAIN_DEPTH_MAX; npc++)
+ ev->pl_u.pl_cc.pl_pc[npc] = (uintfptr_t) 0;
+ break;
case PMCLOG_TYPE_CLOSELOG:
case PMCLOG_TYPE_DROPNOTIFY:
/* nothing to do */
@@ -387,7 +406,7 @@ pmclog_get_event(void *cookie, char **data, ssize_t *len,
default: /* unknown record type */
ps->ps_state = PL_STATE_ERROR;
ev->pl_state = PMCLOG_ERROR;
- return -1;
+ return (-1);
}
ev->pl_offset = (ps->ps_offset += evlen);
diff --git a/lib/libpmc/pmclog.h b/lib/libpmc/pmclog.h
index 90fb193..e3e5c89 100644
--- a/lib/libpmc/pmclog.h
+++ b/lib/libpmc/pmclog.h
@@ -1,7 +1,11 @@
/*-
- * Copyright (c) 2005-2006 Joseph Koshy
+ * Copyright (c) 2005-2007 Joseph Koshy
+ * Copyright (c) 2007 The FreeBSD Foundation
* All rights reserved.
*
+ * Portions of this software were developed by A. Joseph Koshy under
+ * sponsorship from the FreeBSD Foundation and Google, Inc.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -38,6 +42,14 @@ enum pmclog_state {
PMCLOG_ERROR
};
+struct pmclog_ev_callchain {
+ uint32_t pl_pid;
+ uint32_t pl_pmcid;
+ uint32_t pl_cpuflags;
+ uint32_t pl_npc;
+ uintfptr_t pl_pc[PMC_CALLCHAIN_DEPTH_MAX];
+};
+
struct pmclog_ev_dropnotify {
};
@@ -125,6 +137,7 @@ struct pmclog_ev {
struct timespec pl_ts; /* log entry timestamp */
enum pmclog_type pl_type; /* type of log entry */
union { /* log entry data */
+ struct pmclog_ev_callchain pl_cc;
struct pmclog_ev_closelog pl_cl;
struct pmclog_ev_dropnotify pl_dn;
struct pmclog_ev_initialize pl_i;
OpenPOWER on IntegriCloud