3 # Copyright (c) 2002 Dag-Erling Coïdan 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.
37 print(STDERR "usage: mtxstat [-gr] [-a|c|m|t] [-l limit]\n");
42 my %opts; # Command-line options
44 my $limit; # Output limit
46 my $header; # Header line
47 my @names; # Field names
48 my %data; # Mutex data
49 my @list; # List of entries
51 getopts("acgl:mrt", \%opts)
55 if ($opts{'c'} || $opts{'m'} || $opts{'t'});
57 } elsif ($opts{'c'}) {
59 if ($opts{'m'} || $opts{'t'});
61 } elsif ($opts{'m'}) {
65 } elsif ($opts{'t'}) {
69 if ($opts{'l'} !~ m/^\d+$/) {
74 $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
75 open(PIPE, "sysctl -n debug.mutex.prof.stats|")
76 or die("open(): $!\n");
79 @names = split(' ', $header);
80 if (defined($key) && !grep(/^$key$/, @names)) {
81 die("can't find sort key '$key' in header\n");
85 my @fields = split(' ', $_, @names);
89 $entry{$_} = ($_ eq 'name') ? shift(@fields) : 0.0 + shift(@fields);
92 $entry{'name'} =~ s/^(\S+)\s+\((.*)\)$/$2/;
94 my $name = $entry{'name'};
96 if ($entry{'max'} > $data{$name}->{'max'}) {
97 $data{$name}->{'max'} = $entry{'max'};
99 $data{$name}->{'total'} += $entry{'total'};
100 $data{$name}->{'count'} += $entry{'count'};
101 $data{$name}->{'avg'} =
102 $data{$name}->{'total'} / $data{$name}->{'count'};
104 $data{$name} = \%entry;
108 @list = sort({ $data{$a}->{$key} <=> $data{$b}->{$key} }
111 @list = sort(keys(%data));
114 @list = reverse(@list);
118 while (@list > $limit) {
123 printf("%6.0f %12.0f %11.0f %5.0f %-40.40s\n",
125 $data{$_}->{'total'},
126 $data{$_}->{'count'},
128 $data{$_}->{'name'});