#!/bin/sh
# How much of the memory is actually in use?  

# Copyright (c) 2006 by James F. Carter (jimc@math.ucla.edu>
# 2006-08-27, for Maemo-2.0 (Nokia 770)

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You can find the GNU General Public License in your Maemo distribution
# as /usr/share/common-licenses/GPL-2; if it's missing, write to the 
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
# MA 02111-1307, USA.

		# Format of /proc/$PID/maps:
		# start-end mode offset device inode filename
		# start		Where in virtual memory (hex) it was put
		# end		End (hex) of virtual memory range
		# mode		Examples: r-xp rw-p r--p r--s.  Probably p =
		#		copy-on-write, s = everyone sees changes.
		# offset	Seek pointer (hex) in the file where it starts
		# device	Example: 08:03 or 00:00, latter for non-files
		# inode		0 for non-file regions
		# filename	Full path name, or [heap], [stack], [vdso],
		#		or omitted for many non-file regions.
		# This function converts such a row into manageable form,
		# with output: filename length (decimal)
		# where missing filenames are changed to [none]
		# Data is segregated: fil.p has map rows that are present
		# individually in memory, while fil.s has shared rows, present
		# only once for all tasks.

fil=/tmp/memuse
> $fil.p
> $fil.s
    sed -e 's/-/ /' /proc/[0-9]*/maps | \
    while read start end mode offset device inode filename junk ; do
	if [ -z "$filename" ] ; then filename="[none]" ; fi
	case "$mode" in
	    rw?p ) mymode=p ; ;;
	    * ) mymode=s ; ;;
	esac
	eval echo \$filename '$(('0x$end-0x$start'))' >> $fil.$mymode
    done 
		# Postprocessing: shared rows are sorted, and only the biggest
		# for each filename is kept.
> $fil.su
sort -r $fil.s | while read filename size junk ; do
    if [ "$filename" != "$oldfile" ] ; then
	echo $filename $size
	oldfile=$filename
    fi
done > $fil.su
		# Produce the report
awk '{sum += $2} END {print "Private: " (sum/1048576) " Mbytes"}' $fil.p
awk '{sum += $2} END {print "Shared: " (sum/1048576) " Mbytes"}' $fil.su
