Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1#!/bin/sh
  2
  3# Sergey Senozhatsky, 2015
  4# sergey.senozhatsky.work@gmail.com
  5#
  6# This software is licensed under the terms of the GNU General Public
  7# License version 2, as published by the Free Software Foundation, and
  8# may be copied, distributed, and modified under those terms.
  9#
 10# This program is distributed in the hope that it will be useful,
 11# but WITHOUT ANY WARRANTY; without even the implied warranty of
 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13# GNU General Public License for more details.
 14
 15
 16# This program is intended to plot a `slabinfo -X' stats, collected,
 17# for example, using the following command:
 18#   while [ 1 ]; do slabinfo -X >> stats; sleep 1; done
 19#
 20# Use `slabinfo-gnuplot.sh stats' to pre-process collected records
 21# and generate graphs (totals, slabs sorted by size, slabs sorted
 22# by size).
 23#
 24# Graphs can be [individually] regenerate with different ranges and
 25# size (-r %d,%d and -s %d,%d options).
 26#
 27# To visually compare N `totals' graphs, do
 28# slabinfo-gnuplot.sh -t FILE1-totals FILE2-totals ... FILEN-totals
 29#
 30
 31min_slab_name_size=11
 32xmin=0
 33xmax=0
 34width=1500
 35height=700
 36mode=preprocess
 37
 38usage()
 39{
 40	echo "Usage: [-s W,H] [-r MIN,MAX] [-t|-l] FILE1 [FILE2 ..]"
 41	echo "FILEs must contain 'slabinfo -X' samples"
 42	echo "-t 			- plot totals for FILE(s)"
 43	echo "-l 			- plot slabs stats for FILE(s)"
 44	echo "-s %d,%d		- set image width and height"
 45	echo "-r %d,%d		- use data samples from a given range"
 46}
 47
 48check_file_exist()
 49{
 50	if [ ! -f "$1" ]; then
 51		echo "File '$1' does not exist"
 52		exit 1
 53	fi
 54}
 55
 56do_slabs_plotting()
 57{
 58	local file=$1
 59	local out_file
 60	local range="every ::$xmin"
 61	local xtic=""
 62	local xtic_rotate="norotate"
 63	local lines=2000000
 64	local wc_lines
 65
 66	check_file_exist "$file"
 67
 68	out_file=`basename "$file"`
 69	if [ $xmax -ne 0 ]; then
 70		range="$range::$xmax"
 71		lines=$((xmax-xmin))
 72	fi
 73
 74	wc_lines=`cat "$file" | wc -l`
 75	if [ $? -ne 0 ] || [ "$wc_lines" -eq 0 ] ; then
 76		wc_lines=$lines
 77	fi
 78
 79	if [ "$wc_lines" -lt "$lines" ]; then
 80		lines=$wc_lines
 81	fi
 82
 83	if [ $((width / lines)) -gt $min_slab_name_size ]; then
 84		xtic=":xtic(1)"
 85		xtic_rotate=90
 86	fi
 87
 88gnuplot -p << EOF
 89#!/usr/bin/env gnuplot
 90
 91set terminal png enhanced size $width,$height large
 92set output '$out_file.png'
 93set autoscale xy
 94set xlabel 'samples'
 95set ylabel 'bytes'
 96set style histogram columnstacked title textcolor lt -1
 97set style fill solid 0.15
 98set xtics rotate $xtic_rotate
 99set key left above Left title reverse
100
101plot "$file" $range u 2$xtic title 'SIZE' with boxes,\
102	'' $range u 3 title 'LOSS' with boxes
103EOF
104
105	if [ $? -eq 0 ]; then
106		echo "$out_file.png"
107	fi
108}
109
110do_totals_plotting()
111{
112	local gnuplot_cmd=""
113	local range="every ::$xmin"
114	local file=""
115
116	if [ $xmax -ne 0 ]; then
117		range="$range::$xmax"
118	fi
119
120	for i in "${t_files[@]}"; do
121		check_file_exist "$i"
122
123		file="$file"`basename "$i"`
124		gnuplot_cmd="$gnuplot_cmd '$i' $range using 1 title\
125			'$i Memory usage' with lines,"
126		gnuplot_cmd="$gnuplot_cmd '' $range using 2 title \
127			'$i Loss' with lines,"
128	done
129
130gnuplot -p << EOF
131#!/usr/bin/env gnuplot
132
133set terminal png enhanced size $width,$height large
134set autoscale xy
135set output '$file.png'
136set xlabel 'samples'
137set ylabel 'bytes'
138set key left above Left title reverse
139
140plot $gnuplot_cmd
141EOF
142
143	if [ $? -eq 0 ]; then
144		echo "$file.png"
145	fi
146}
147
148do_preprocess()
149{
150	local out
151	local lines
152	local in=$1
153
154	check_file_exist "$in"
155
156	# use only 'TOP' slab (biggest memory usage or loss)
157	let lines=3
158	out=`basename "$in"`"-slabs-by-loss"
159	`cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\
160		egrep -iv '\-\-|Name|Slabs'\
161		| awk '{print $1" "$4+$2*$3" "$4}' > "$out"`
162	if [ $? -eq 0 ]; then
163		do_slabs_plotting "$out"
164	fi
165
166	let lines=3
167	out=`basename "$in"`"-slabs-by-size"
168	`cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\
169		egrep -iv '\-\-|Name|Slabs'\
170		| awk '{print $1" "$4" "$4-$2*$3}' > "$out"`
171	if [ $? -eq 0 ]; then
172		do_slabs_plotting "$out"
173	fi
174
175	out=`basename "$in"`"-totals"
176	`cat "$in" | grep "Memory used" |\
177		awk '{print $3" "$7}' > "$out"`
178	if [ $? -eq 0 ]; then
179		t_files[0]=$out
180		do_totals_plotting
181	fi
182}
183
184parse_opts()
185{
186	local opt
187
188	while getopts "tlr::s::h" opt; do
189		case $opt in
190			t)
191				mode=totals
192				;;
193			l)
194				mode=slabs
195				;;
196			s)
197				array=(${OPTARG//,/ })
198				width=${array[0]}
199				height=${array[1]}
200				;;
201			r)
202				array=(${OPTARG//,/ })
203				xmin=${array[0]}
204				xmax=${array[1]}
205				;;
206			h)
207				usage
208				exit 0
209				;;
210			\?)
211				echo "Invalid option: -$OPTARG" >&2
212				exit 1
213				;;
214			:)
215				echo "-$OPTARG requires an argument." >&2
216				exit 1
217				;;
218		esac
219	done
220
221	return $OPTIND
222}
223
224parse_args()
225{
226	local idx=0
227	local p
228
229	for p in "$@"; do
230		case $mode in
231			preprocess)
232				files[$idx]=$p
233				idx=$idx+1
234				;;
235			totals)
236				t_files[$idx]=$p
237				idx=$idx+1
238				;;
239			slabs)
240				files[$idx]=$p
241				idx=$idx+1
242				;;
243		esac
244	done
245}
246
247parse_opts "$@"
248argstart=$?
249parse_args "${@:$argstart}"
250
251if [ ${#files[@]} -eq 0 ] && [ ${#t_files[@]} -eq 0 ]; then
252	usage
253	exit 1
254fi
255
256case $mode in
257	preprocess)
258		for i in "${files[@]}"; do
259			do_preprocess "$i"
260		done
261		;;
262	totals)
263		do_totals_plotting
264		;;
265	slabs)
266		for i in "${files[@]}"; do
267			do_slabs_plotting "$i"
268		done
269		;;
270	*)
271		echo "Unknown mode $mode" >&2
272		usage
273		exit 1
274	;;
275esac