diff --git a/stackcollapse-pmc.pl b/stackcollapse-pmc.pl new file mode 100755 index 00000000..c78fb96c --- /dev/null +++ b/stackcollapse-pmc.pl @@ -0,0 +1,74 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2014 Ed Maste. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# stackcollapse-pmc.pl collapse hwpmc samples into single lines. +# +# Parses a list of multiline stacks generated by "hwpmc -G", and outputs a +# semicolon-separated stack followed by a space and a count. +# +# Usage: +# pmcstat -S unhalted-cycles -O pmc.out +# pmcstat -R pmc.out -z16 -G pmc.graph +# stackcollapse-pmc.pl pmc.graph > pmc.stack +# +# Example input: +# +# 03.07% [17] witness_unlock @ /boot/kernel/kernel +# 70.59% [12] __mtx_unlock_flags +# 16.67% [2] selfdfree +# 100.0% [2] sys_poll +# 100.0% [2] amd64_syscall +# 08.33% [1] pmap_ts_referenced +# 100.0% [1] vm_pageout +# 100.0% [1] fork_exit +# ... +# +# Example output: +# +# amd64_syscall;sys_poll;selfdfree;__mtx_unlock_flags;witness_unlock 2 +# amd64_syscall;sys_poll;pmap_ts_referenced;__mtx_unlock_flagsgeout;fork_exit 1 +# ... + +use warnings; +use strict; + +my @stack; +my $prev_count; +my $prev_indent = -1; + +foreach (<>) { + if (m/^( *)[0-9.]+% \[([0-9]+)\]\s*(\S+)/) { + my $indent = length($1); + if ($indent <= $prev_indent) { + print join(';', reverse(@stack[0 .. $prev_indent])) . + " $prev_count\n"; + } + $stack[$indent] = $3; + $prev_count = $2; + $prev_indent = $indent; + } +} +print join(';', reverse(@stack[0 .. $prev_indent])) . " $prev_count\n";