[Python-checkins] r50908 - python/branches/bcannon-sandboxing/Objects/trackedmalloc.c

brett.cannon python-checkins at python.org
Fri Jul 28 19:21:15 CEST 2006


Author: brett.cannon
Date: Fri Jul 28 19:21:14 2006
New Revision: 50908

Added:
   python/branches/bcannon-sandboxing/Objects/trackedmalloc.c
Log:
Major oversight of forgetting to check in the tracking malloc functions to begin with.  =)


Added: python/branches/bcannon-sandboxing/Objects/trackedmalloc.c
==============================================================================
--- (empty file)
+++ python/branches/bcannon-sandboxing/Objects/trackedmalloc.c	Fri Jul 28 19:21:14 2006
@@ -0,0 +1,155 @@
+#include "Python.h"
+#include <malloc.h>
+
+/*
+    Add accountability to memory allocation.
+
+    The goal of these functions is to allow for all memory to be tracked based
+    on how much is being (roughly) used, and for what.  
+
+    The APIs that need to be covered are PyObject_New(), Pyobject_Malloc(),
+    PyMem_Malloc(), the realloc/free mates, the macro variants, and the GC
+    variants.
+
+    * PyObject_New()/PyObject_NewVar()/PyObject_Del()
+	Uses PyObject_T_*()
+    * PyObject_NEW()/PyObject_NEW_VAR()/PyObject_DEL()
+	Uses PyObject_T_*()
+    * PyObject_MALLOC()/PyObject_REALLOC()/PyObject_FREE()
+	Change over to PyObject_T_*()
+    * PyObject_Malloc()/PyObject_Realloc()/PyObject_Free()
+	XXX
+    * PyObject_GC_New()/PyObject_GC_NewVar()/PyObject_GC_Del()
+	Uses _PyObject_GC_TrackedMalloc()
+    * _PyObject_GC_Malloc()
+	Changed to _PyObject_GC_TrackedMalloc()
+    * PyObject_GC_Resize()
+	Uses PyObject_T_MALLOC()
+    * PyMem_Malloc()/PyMem_Realloc()/PyMem_Free()
+	XXX
+    * PyMem_MALLOC()/PyMem_REALLOC()/PyMem_FREE()
+	XXX
+    * malloc()/realloc()/free()
+	XXX
+
+    In order to properly track memory usage, we must handle both memory handed
+    out by pymalloc as well as memory from malloc().  For pymaloc, we need to
+    first find out if pymalloc is managing the memory, and if that is true then
+    how big of a chunk of memory was given for the pointer.
+    For malloc(), we need to either use functions provided by the C library
+    (for glibc, see
+    http://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html).
+*/
+
+unsigned long Py_ProcessMemUsage = 0;
+
+static const char *UNKNOWN_WHAT = "<unknown>";
+
+
+/*
+   Track an anonymous chunk of memory.
+*/
+int
+PyObject_TrackMemory(const char *what, size_t nbytes)
+{
+    what = what ? what : UNKNOWN_WHAT;
+
+    Py_ProcessMemUsage += nbytes;
+
+    return 1;
+}
+
+/*
+   Stop tracking an anonymous chunk of memory.
+*/
+int
+PyObject_UntrackMemory(const char *what, size_t nbytes)
+{
+    what = what ? what : UNKNOWN_WHAT;
+
+    Py_ProcessMemUsage -= nbytes;
+
+    return 1;
+}
+
+/*
+   Track the memory created by PyObject_Maloc().
+*/
+void *
+PyObject_TrackedMalloc(const char *what, size_t nbytes)
+{
+    struct mallinfo before = mallinfo();
+    void *allocated = NULL;
+    size_t used = 0;
+
+    allocated = PyObject_Malloc(nbytes);
+
+    if (!allocated)
+	return NULL;
+
+    if (PyMalloc_ManagesMemory(allocated)) {
+	used = PyMalloc_AllocatedSize(allocated);
+    }
+    else {
+	used = mallinfo().uordblks - before.uordblks;
+    }
+
+    PyObject_TrackMemory(what, used);
+
+    return allocated;
+}
+
+/*
+   Track the realloc of memory cretaed by PyObject_Malloc().
+
+   XXX really need to have reason string passed in?
+*/
+void *
+PyObject_TrackedRealloc(const char *what, void *to_resize, size_t new_size)
+{
+    struct mallinfo before = mallinfo();
+    void *allocated = NULL;
+    size_t size_delta = 0;
+
+    if (PyMalloc_ManagesMemory(to_resize)) {
+	size_delta = PyMalloc_AllocatedSize(to_resize);
+    }
+
+    allocated = PyObject_Realloc(to_resize, new_size);
+
+    if (!allocated)
+	return NULL;
+
+    if (PyMalloc_ManagesMemory(allocated)) {
+	size_delta = PyMalloc_AllocatedSize(allocated) - size_delta;
+    }
+    else {
+	size_delta = mallinfo().uordblks - before.uordblks;
+    }
+
+    PyObject_TrackMemory(what, size_delta);
+
+    return allocated;
+}
+
+/*
+   Untrack memory created by PyObject_Malloc().
+*/
+void
+PyObject_TrackedFree(const char *what, void *to_free)
+{
+    struct mallinfo before = mallinfo();
+    size_t freed = 0;
+
+    if (PyMalloc_ManagesMemory(to_free)) {
+	freed = PyMalloc_AllocatedSize(to_free);
+    }
+
+    PyObject_Free(to_free);
+
+    if (!freed) {
+	freed = before.uordblks - mallinfo().uordblks;
+    }
+
+    PyObject_UntrackMemory(what, freed);
+}


More information about the Python-checkins mailing list