[Python-checkins] r50920 - in python/branches/bcannon-sandboxing: Include/objimpl.h Include/pymem.h Objects/trackedmalloc.c Python/sysmodule.c
brett.cannon
python-checkins at python.org
Sat Jul 29 01:45:00 CEST 2006
Author: brett.cannon
Date: Sat Jul 29 01:44:59 2006
New Revision: 50920
Modified:
python/branches/bcannon-sandboxing/Include/objimpl.h
python/branches/bcannon-sandboxing/Include/pymem.h
python/branches/bcannon-sandboxing/Objects/trackedmalloc.c
python/branches/bcannon-sandboxing/Python/sysmodule.c
Log:
Add tracking at the type level.
Uses a linked list to store types since easy to do in pure C and thus minimize
bootstrapping issues of using Python objects when tracking memory allocation.
Plus the number of types created during the lifetime of a Python process is
actually rather small.
Modified: python/branches/bcannon-sandboxing/Include/objimpl.h
==============================================================================
--- python/branches/bcannon-sandboxing/Include/objimpl.h (original)
+++ python/branches/bcannon-sandboxing/Include/objimpl.h Sat Jul 29 01:44:59 2006
@@ -95,6 +95,7 @@
the raw memory.
*/
PyAPI_DATA(unsigned long) Py_ProcessMemUsage;
+PyAPI_FUNC(PyObject *) Py_MemoryUsage(PyObject *, PyObject *);
PyAPI_FUNC(int) PyMalloc_ManagesMemory(void *);
PyAPI_FUNC(size_t) PyMalloc_AllocatedSize(void *);
PyAPI_FUNC(void *) PyObject_Malloc(size_t);
Modified: python/branches/bcannon-sandboxing/Include/pymem.h
==============================================================================
--- python/branches/bcannon-sandboxing/Include/pymem.h (original)
+++ python/branches/bcannon-sandboxing/Include/pymem.h Sat Jul 29 01:44:59 2006
@@ -61,12 +61,6 @@
#define PyMem_REALLOC PyObject_REALLOC
#define PyMem_FREE PyObject_FREE
-#elif define (Py_TRACK_MEMORY)
-
-#define PyMem_MALLOC(size) PyObject_T_MALLOC("", size)
-#define PyMem_REALLOC(size) PyObject_T_REALLOC("", size)
-#define PyMem_FREE(size) PyObject_T_FREE("", size)
-
#else /* ! PYMALLOC_DEBUG */
/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL
Modified: python/branches/bcannon-sandboxing/Objects/trackedmalloc.c
==============================================================================
--- python/branches/bcannon-sandboxing/Objects/trackedmalloc.c (original)
+++ python/branches/bcannon-sandboxing/Objects/trackedmalloc.c Sat Jul 29 01:44:59 2006
@@ -26,9 +26,9 @@
* PyObject_GC_Resize()
Uses PyObject_T_MALLOC()
* PyMem_Malloc()/PyMem_Realloc()/PyMem_Free()
- Uses PyMem_MALLOC(), etc.
+ XXX
* PyMem_MALLOC()/PyMem_REALLOC()/PyMem_FREE()
- Change to PyObject_T_*("", size)
+ XXX
* malloc()/realloc()/free()
XXX
@@ -52,6 +52,72 @@
static const char *UNKNOWN_WHAT = "<unknown>";
+struct mem_item {
+ struct mem_item *next;
+ const char *type;
+ unsigned long using;
+};
+
+static struct mem_item mem_sentinel = {NULL, NULL, 0};
+static struct mem_item *mem_head = &mem_sentinel;
+static Py_ssize_t mem_item_count = 0;
+
+
+PyObject *
+Py_MemoryUsage(PyObject *self, PyObject *ignore)
+{
+ struct mem_item *cur_mem = mem_head;
+ PyObject *mem_dict = PyDict_New();
+ Py_ssize_t x = 0;
+ int int_result = 0;
+
+ if (!mem_dict)
+ return NULL;
+
+ for (x=0; x < mem_item_count; x+=1) {
+ cur_mem = cur_mem->next;
+ PyObject *long_obj = PyLong_FromUnsignedLong(cur_mem->using);
+ if (!long_obj)
+ return NULL;
+ int_result = PyDict_SetItemString(mem_dict, cur_mem->type, long_obj);
+ Py_DECREF(long_obj);
+
+ if (int_result < 0)
+ return NULL;
+ }
+
+ return mem_dict;
+}
+
+/* XXX remove entries where memory usage is zero? */
+static struct mem_item *
+find_mem_entry(const char *what)
+{
+ struct mem_item *cur_mem = mem_head;
+
+ what = what ? what : UNKNOWN_WHAT;
+
+ while (cur_mem->next) {
+ cur_mem = cur_mem->next;
+
+ if (strcmp(what, cur_mem->type) == 0)
+ return cur_mem;
+ }
+
+ cur_mem->next = malloc(sizeof(struct mem_item));
+ cur_mem = cur_mem->next;
+
+ if (!cur_mem)
+ return NULL;
+
+ mem_item_count += 1;
+
+ cur_mem->next = NULL;
+ cur_mem->type = what; /* XXX memcpy? */
+ cur_mem->using = 0;
+
+ return cur_mem;
+}
/*
Track an anonymous chunk of memory.
@@ -59,8 +125,13 @@
int
PyObject_TrackMemory(const char *what, size_t nbytes)
{
- what = what ? what : UNKNOWN_WHAT;
+ struct mem_item *mem_entry = find_mem_entry(what);
+ if (!mem_entry)
+ return 0;
+
+ /* XXX check for overflow. */
+ mem_entry->using += nbytes;
Py_ProcessMemUsage += nbytes;
return 1;
@@ -72,8 +143,13 @@
int
PyObject_UntrackMemory(const char *what, size_t nbytes)
{
- what = what ? what : UNKNOWN_WHAT;
+ struct mem_item *mem_entry = find_mem_entry(what);
+
+ if (!mem_entry)
+ return 0;
+ /* XXX check for hitting < 0. */
+ mem_entry->using -= nbytes;
Py_ProcessMemUsage -= nbytes;
return 1;
Modified: python/branches/bcannon-sandboxing/Python/sysmodule.c
==============================================================================
--- python/branches/bcannon-sandboxing/Python/sysmodule.c (original)
+++ python/branches/bcannon-sandboxing/Python/sysmodule.c Sat Jul 29 01:44:59 2006
@@ -782,6 +782,7 @@
#endif
{"settrace", sys_settrace, METH_O, settrace_doc},
{"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
+ {"memoryusage", Py_MemoryUsage, METH_NOARGS, "XXX"},
{NULL, NULL} /* sentinel */
};
More information about the Python-checkins
mailing list