changeset 1064:753b0258a5be

New option for tracking memory usage over time. Adding --track-memory will make the runtime print out a line with the current and peak memory usage.
author Martin Geisler <mg@daimi.au.dk>
date Fri, 09 Jan 2009 17:17:05 +0100
parents 8bca4980563f
children 9f176022087d
files viff/runtime.py viff/util.py
diffstat 2 files changed, 47 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/viff/runtime.py	Thu Jan 08 11:31:57 2009 +0100
+++ b/viff/runtime.py	Fri Jan 09 17:17:05 2009 +0100
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright 2007, 2008 VIFF Development Team.
+# Copyright 2007, 2008, 2009 VIFF Development Team.
 #
 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
 #
@@ -39,9 +39,10 @@
 from collections import deque
 
 from viff.field import GF256, FieldElement
-from viff.util import wrapper, rand, deep_wait
+from viff.util import wrapper, rand, deep_wait, track_memory_usage
 
 from twisted.internet import reactor
+from twisted.internet.task import LoopingCall
 from twisted.internet.error import ConnectionDone, CannotListenError
 from twisted.internet.defer import Deferred, DeferredList, gatherResults, succeed
 from twisted.internet.defer import maybeDeferred
@@ -428,6 +429,8 @@
                          help="Enable extra debug output for deferreds.")
         group.add_option("--profile", action="store_true",
                          help="Collect and print profiling information.")
+        group.add_option("--track-memory", action="store_true",
+                         help="Track memory usage over time.")
 
         try:
             # Using __import__ since we do not use the module, we are
@@ -441,7 +444,8 @@
                             security_parameter=30,
                             ssl=have_openssl,
                             deferred_debug=False,
-                            profile=False)
+                            profile=False,
+                            track_memory=False)
 
     def __init__(self, player, threshold, options=None):
         """Initialize runtime.
@@ -766,6 +770,13 @@
     Please see the example applications for more examples.
 
     """
+    if options and options.track_memory:
+        lc = LoopingCall(track_memory_usage)
+        # Five times per second seems like a fair value. Besides, the
+        # kernel will track the peak memory usage for us anyway.
+        lc.start(0.2)
+        reactor.addSystemEventTrigger("after", "shutdown", track_memory_usage)
+
     if runtime_class is None:
         # The import is put here because of circular depencencies
         # between viff.runtime and viff.passive.
--- a/viff/util.py	Thu Jan 08 11:31:57 2009 +0100
+++ b/viff/util.py	Fri Jan 09 17:17:05 2009 +0100
@@ -1,4 +1,4 @@
-# Copyright 2007, 2008 VIFF Development Team.
+# Copyright 2007, 2008, 2009 VIFF Development Team.
 #
 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
 #
@@ -356,6 +356,38 @@
 
     return profile_wrapper
 
+
+def memory_usage():
+    """Read memory usage of the current process."""
+    status = None
+    result = {'peak': 0, 'rss': 0}
+    try:
+        # This will only work on systems with a /proc file system
+        # (like Linux).
+        status = open('/proc/self/status', 'r')
+        for line in status:
+            parts = line.split()
+            key = parts[0][2:-1].lower()
+            if key in result:
+                result[key] = int(parts[1])
+    finally:
+        if status is not None:
+            status.close()
+    return result
+
+
+_last_memory_usage = None
+
+
+def track_memory_usage():
+    """Print memory usage if changed since last time."""
+    global _last_memory_usage
+    usage = memory_usage()
+    if usage != _last_memory_usage:
+        print ", ".join(["%s: %.1f MiB" % (key, value/1024.0)
+                         for key, value in usage.iteritems()])
+        _last_memory_usage = usage
+
 if __name__ == "__main__":
     import doctest    #pragma NO COVER
     doctest.testmod() #pragma NO COVER