From 86277bac23504de54f439ce27b121d2c24eac93d Mon Sep 17 00:00:00 2001 From: jkoshy Date: Mon, 3 Dec 2007 11:15:46 +0000 Subject: Add callchain parsing to -lpmc. Sponsored by: FreeBSD Foundation and Google Inc. --- lib/libpmc/pmclog.c | 25 ++++++++++++++++++++++--- lib/libpmc/pmclog.h | 15 ++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'lib/libpmc') 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; -- cgit v1.1