#!/usr/bin/env python
#
#
# Copyright 2014, NICTA
#
# This software may be distributed and modified according to the terms of
# the BSD 2-Clause license. Note that NO WARRANTY is provided.
# See "LICENSE_BSD2.txt" for details.
#
# @TAG(NICTA_BSD)
#

'''
Monitors the peak memory usage of a process and its children. Usage is similar
to the UNIX `time` utility.
'''

import subprocess, sys, threading, time

PSUTIL_NOT_AVAILABLE=False
try:
    import psutil
except ImportError:
  PSUTIL_NOT_AVAILABLE=True

PSUTIL2 = psutil.version_info >= (2, 0) if not PSUTIL_NOT_AVAILABLE else False

if PSUTIL_NOT_AVAILABLE:
    def get_usage(proc):
        return 0
    def get_total_usage(proc):
        return 0
else:
  def get_usage(proc):
    '''Retrieve the memory usage of a particular psutil process without its
    children. We use the proportional set size, which accounts for shared pages
    to give us a more accurate total usage.'''
    assert isinstance(proc, psutil.Process)
    try:
        if PSUTIL2:
          return sum([m.pss for m in proc.memory_maps(grouped=True)])
        else:
          return sum([m.pss for m in proc.get_memory_maps(grouped=True)])
    except psutil.AccessDenied:
        # If we don't have permission to read a particular process,
        # just return 0.
        return 0

  def get_total_usage(pid):
    '''Retrieve the memory usage of a process by PID including its children. We
    ignore NoSuchProcess errors to mask subprocesses exiting while the cohort
    continues.'''
    total = 0

    # Fetch parent's usage.
    try:
        p = psutil.Process(pid)
        total += get_usage(p)
        if PSUTIL2:
          children = p.children(recursive=True) #pylint: disable=E1123
        else:
          children = p.get_children(recursive=True) #pylint: disable=E1123
    except psutil.NoSuchProcess:
        return 0

    # Fetch usage of children.
    for proc in children:
        try:
            total += get_usage(proc)
        except psutil.NoSuchProcess:
            pass

    return total

class Poller(threading.Thread):
    def __init__(self, pid):
        super(Poller, self).__init__()
        # Daemonise ourselves to avoid delaying exit of the process of our
        # calling thread.
        self.daemon = True
        self.pid = pid
        self.high = 0
        self.finished = False
        self.started = threading.Semaphore(0)

    def run(self):
        # Fetch a sample, and notify others that we have started.
        self.high = get_total_usage(self.pid)
        self.started.release()

        #
        # Poll the process periodically to track a high water mark of its
        # memory usage.
        #
        # We poll quickly at the beginning and use exponential backout until we
        # hit 1 second to try and get better stats on short-lived processes.
        #
        polling_interval = 0.01
        while not self.finished:
            time.sleep(polling_interval)
            usage = get_total_usage(self.pid)
            if usage > self.high:
                self.high = usage
            if polling_interval < 1.0:
                polling_interval = min(polling_interval * 1.5, 1.0)

    def peak_mem_usage(self):
        return self.high

    def __enter__(self):
        return self

    def __exit__(self, *_):
        self.finished = True

def process_poller(pid):
    '''Initiate polling of a subprocess. This is intended to be used in a
    `with` block.'''
    # Create a new thread and start it up.
    p = Poller(pid)
    p.start()

    # Wait for the thread to record at least one sample before continuing.
    p.started.acquire()

    return p

def main():
    if len(sys.argv) <= 1 or sys.argv[1] in ['-?', '--help']:
        print >>sys.stderr, 'Usage: %s command args...\n Measure peak memory ' \
            'usage of a command' % sys.argv[0]
        return -1

    if PSUTIL_NOT_AVAILABLE:
        print("Error: 'psutil' module not available. Run\n"
              "\n"
              "    pip install --user psutil\n"
              "\n"
              "to install.")
        sys.exit(1)

    # Run the command requested.
    try:
        p = subprocess.Popen(sys.argv[1:])
    except OSError:
        print >>sys.stderr, 'command not found'
        return -1

    high = 0
    try:
        with process_poller(p.pid) as m: #pylint: disable=E1101
            p.communicate()
            high = m.peak_mem_usage()
    except KeyboardInterrupt:
        # The user Ctrl-C-ed us. Fake an error return code.
        p.returncode = -1

    print >>sys.stderr, 'Peak usage %d bytes' % high

    return p.returncode

if __name__ == '__main__':
    sys.exit(main())
