#!/usr/bin/env perl
#
# usage: ./rampages.pl | sort -n

use strict;
use warnings;

my $tsum = 0;
my %esum;

opendir(my $dh, '/proc');
while (my $pid = readdir($dh)) {
	next unless ($pid =~ m/^[0-9]+$/);
	#print "$pid\n";
	my $fh;
	my $procname = "???";
	if (!open $fh, "<", "/proc/$pid/status") {
		print "99999999 inaccessible-status($pid)\n";
		next;
	};
	while (my $ln = <$fh>) {
		if ($ln =~ m/^Name:/) {
			$procname = $ln;
			$procname =~ s/[^\s]+\s+//;
			$procname =~ s/\s*$//;
			last;
		}
	}
	close $fh;
	#print "$procname\n";
	
	my $psum = 0;
	my $lo=0; my $hi=0; my $perm=0; my $dev=0; my $inode=0; my $tag="";
	if (!open $fh, "<", "/proc/$pid/smaps") {
		print "99999999 inaccessible-smaps($pid/$procname)\n";
		next;
	}
	while (my $ln = <$fh>) {
		if ($ln =~ m/^Pss:\s+([0-9]+)/) {
			my $sz = $1;
			my $type = ($inode > 0)? "f":"p";
			$psum += $sz;
			$tsum += $sz;
			printf "%8.1f %5d \033[35m%-20s\033[0m %s %s\n", $sz/1024,$pid,$procname,$type,$tag;
			next;
		}
		if ($ln =~ m/^[A-Z]/) {
			next;
		}
		if (my @h = $ln =~ m/^([0-9a-f]+)-([0-9a-f]+)\s+([rwxp-]{4})\s+[0-9a-f]+\s+([0-9a-f:]{5})\s+([0-9]+)\s*(.*)/) {
			($lo,$hi,$perm,$dev,$inode,$tag) = @h;
			next;
		}
	}
	$esum{$procname} += $psum;
	printf "%8.1f %5s \033[36msum(%s)\033[0m\n", $psum/1024, $pid, $procname;
}
closedir $dh;

for my $procname (keys %esum) {
	printf "%8.1f \033[36mesum(%s)\033[0m\n", $esum{$procname}/1024, $procname;
}

printf "%8.1f \033[36msum(*)\033[0m\n", $tsum/1024;
