"""based on http://www.pixelbeat.org/scripts/ps_mem.py
"""
import sys
import os

PAGESIZE = os.sysconf("SC_PAGE_SIZE") / 1024 #KiB

def human(num, power="Ki"):
    powers = ["Ki", "Mi", "Gi", "Ti"]
    while num >= 1000: #4 digits
        num /= 1024.0
        power = powers[powers.index(power) + 1]
    return "%.1f %s" % (num, power)

def _memprint(pid, out=sys.stdout):
    have_pss = False
    private_lines = []
    shared_lines = []
    pss_lines = []
    try:
        rss = int(open("/proc/%s/statm" % pid).readline().split()[1]) * PAGESIZE
    except IOError:
        print 'unknown process', pid
        return
    if os.path.exists("/proc/%s/smaps" % pid): #stat
        for line in open("/proc/%s/smaps" % pid).readlines(): #open
            if line.startswith("Shared"):
                shared_lines.append(line)
            elif line.startswith("Private"):
                private_lines.append(line)
            elif line.startswith("Pss"):
                have_pss = True
                pss_lines.append(line)
        shared = sum([int(line.split()[1]) for line in shared_lines])
        private = sum([int(line.split()[1]) for line in private_lines])
        #Note shared + Private = Rss above
        #The Rss in smaps includes video card mem etc.
        if have_pss:
            pss_adjust = 0.5 #add 0.5KiB as this average error due to trunctation
            pss = sum([float(line.split()[1])+pss_adjust for line in pss_lines])
            shared = pss - private
    elif (2,6,1) <= kv <= (2,6,9):
        shared = 0 #lots of overestimation, but what can we do?
        private = rss
    else:
        shared = int(open("/proc/%s/statm" % pid).readline().split()[2])
        shared *= PAGESIZE
        private = rss - shared
    print >> out, " Private  +   Shared  =  RAM used"
    print >> out, "%8sB + %8sB = %8sB" % (human(private), human(shared), human(rss))

def memprint(msg=None, out=sys.stdout):
    print >> out, '-' * 20
    if msg:
        print >> out, msg
    _memprint(os.getpid(), out)
    print >> out, '-' * 20

if __name__ == '__main__':
    pid = int(sys.argv[1])
    _memprint(pid)
