#!/usr/bin/perl
use warnings;
use strict;

my $overall = 0;
my %out = ();

opendir(my $dh, '/proc/') || die "Can't open /proc: $!";
my @pids = grep { -d "/proc/".$_ && /^[0-9]+$/} readdir($dh);
closedir($dh);
foreach my $pid (@pids) {
    my $sum = 0;
    next unless -d "/proc/$pid";
    print ".";
    foreach my $swap ( `grep Swap /proc/$pid/smaps 2>/dev/null` ){
        next unless $swap;
        $swap = (split(/\s+/,$swap))[-2];
        $sum += $swap;
        $overall += $swap;
    }

    my $progname = `ps -p $pid  -o comm --no-headers`;
    chomp($progname);
    $sum = t($sum);
    $out{$pid} = [$progname,$sum] unless $sum == 0;
}
$overall = t($overall);
my $total = t(`grep SwapTotal /proc/meminfo`);
print "\nSwapTotal: $total MB\n";
print "SwapUsed:   $overall MB\n";
print "========================================\n";
print "MB\t%\tPID\tprocess\n";
foreach my $pid ( sort{ $out{$b}[1] <=> $out{$a}[1] } keys(%out) ) {
  print $out{$pid}[1]."\t".p($total,$out{$pid}[1])."\t".$pid."\t".$out{$pid}[0]."\n";
}

sub t {
    my $x = shift;
    $x = (split(/\s+/,$x))[-2] if $x =~ /\s/;
    sprintf("%.1f",$x/1024);
}

sub p {
    my $total = shift;
    my $x = shift;
    return sprintf("%.1f",100*$x/$total);
}