3 # Copyright (c) 2002 Dag-Erling Smørgrav
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer
11 # in this position and unchanged.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # 3. The name of the author may not be used to endorse or promote products
16 # derived from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 print(STDERR "usage: mtxstat [-gr] [-a|c|m|t] [-l limit]\n");
41 my %opts; # Command-line options
43 my $limit; # Output limit
45 my $header; # Header line
46 my @names; # Field names
47 my %data; # Mutex data
48 my @list; # List of entries
50 getopts("acgl:mrt", \%opts)
54 if ($opts{'c'} || $opts{'m'} || $opts{'t'});
56 } elsif ($opts{'c'}) {
58 if ($opts{'m'} || $opts{'t'});
60 } elsif ($opts{'m'}) {
64 } elsif ($opts{'t'}) {
68 if ($opts{'l'} !~ m/^\d+$/) {
73 $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
74 open(PIPE, "sysctl -n debug.mutex.prof.stats|")
75 or die("open(): $!\n");
78 @names = split(' ', $header);
79 if (defined($key) && !grep(/^$key$/, @names)) {
80 die("can't find sort key '$key' in header\n");
84 my @fields = split(' ', $_, @names);
88 $entry{$_} = ($_ eq 'name') ? shift(@fields) : 0.0 + shift(@fields);
91 $entry{'name'} =~ s/^(\S+)\s+\((.*)\)$/$2/;
93 my $name = $entry{'name'};
95 if ($entry{'max'} > $data{$name}->{'max'}) {
96 $data{$name}->{'max'} = $entry{'max'};
98 $data{$name}->{'total'} += $entry{'total'};
99 $data{$name}->{'count'} += $entry{'count'};
100 $data{$name}->{'avg'} =
101 $data{$name}->{'total'} / $data{$name}->{'count'};
103 $data{$name} = \%entry;
107 @list = sort({ $data{$a}->{$key} <=> $data{$b}->{$key} }
110 @list = sort(keys(%data));
113 @list = reverse(@list);
117 while (@list > $limit) {
122 printf("%6.0f %12.0f %11.0f %5.0f %-40.40s\n",
124 $data{$_}->{'total'},
125 $data{$_}->{'count'},
127 $data{$_}->{'name'});