#! /usr/bin/perl
# Listing 2
# Program: 	vmem
# Usage:	vmem process-id
# Output:	The memory usage for the process

eval "exec perl -S $0 ${1+\"$@\"}"
	if $running_under_some_shell;

require "open2.pl";

if ($#ARGV < 0 || @ARGV[0] eq '-?') {
	die "Usage: vmem pid\n";
} else {
	$nbpp = &get_page_size();
	@regions = &get_regions(@ARGV[0]);
	if ($#regions == -1) {
		die "PID $apid is invalid.\n";
	}
	@reg_table = &get_reg_info(@regions);
	($spsz, $ppsz, $svl, $pvl) = 
		&get_reg_size(@reg_table);
	print "SPSZ	PPSZ	SVL	PVL\n";
	print $spsz * $nbpp, "\t", $ppsz * $nbpp, "\t", $svl * $nbpp, "\t", 
		$pvl * $nbpp, "\n";
	0;
}

# Function: 	get_page_size
# Usage:	&get_page_size();
# Returns:	The size of a page in k
sub get_page_size
{
	local($nbpp);

	open(IMMU, "/usr/include/sys/immu.h") || die "Can't open immu.h\n";
	while (<IMMU>) {
		if (/#define[\s]+NBPP[\s]/o) {
			($nbpp) = (split)[2];
		}
	}
	close(IMMU);
	int($nbpp / 1024 + .5);
}

# Function: 	get_regions
# Usage:	&get_regions(process-id)
# Return:	Region lines from the full process table

sub get_regions
{
	local($pid) = @_;
	local(@regs) = ();

	&open2("INCRASH", "OUTCRASH", "crash 2>/dev/null");
	print OUTCRASH "proc -f #$pid\n";
	close(OUTCRASH);
	while (<INCRASH>) {
		last if (/^[\s]*preg reg/o);
	}
	while (<INCRASH>) {
		last if (/^[\s]*$/o);
		($region) = (split)[2];
		push(@regs, $region);
	}
	close(INCRASH);
	@regs;
}

# Function:	get_reg_info
# Usage:	&get_reg_info(region-list)
# Return:	Lines from region table display

sub get_reg_info
{
	local($regs) = join(" ", @_);
	local(@reglist) = ();

	&open2("INCRASH", "OUTCRASH", "crash 2>/dev/null");
	print OUTCRASH "region ", $regs, "\n";
	close(OUTCRASH);
	@reglist = <INCRASH>;
	close(INCRASH);
	@reglist;
}

# Function: get_reg_size
# Usage:		&get_reg_size(region-list)
# Returns:	(shared full process space,
#		 private full process space,
#		 shared in-core process space,
#		 private in-core process space)

sub get_reg_size
{
	local($spsz, $ppsz, $svl, $pvl, $psz, $vl, $field2, $field3);

	foreach (@_) {
		if (/^SLOT/o) {
			($field2, $field3) = (split)[1,2];
		}
		elsif (/stxt/o) {
			if ($field2 eq 'PSZ') {
				($psz, $vl) = (split)[2,3];
			}
			else {
				($psz, $vl) = (split)[3,4];
			}
			$spsz += $psz;
			$svl += $vl;
		}
		elsif (/priv/o) {
			if ($field2 eq 'PSZ') {
				($psz, $vl) = (split)[2,3];
			}
			else {
				($psz, $vl) = (split)[3,4];
			}
			$ppsz += $psz;
			$pvl += $vl;
		}
	}
	($spsz, $ppsz, $svl, $pvl);
}

