summaryrefslogtreecommitdiff
path: root/tools/allocation_tracking/alloc_hook.pyx
diff options
context:
space:
mode:
authorThouis (Ray) Jones <thouis@gmail.com>2012-06-18 11:50:28 +0200
committerThouis (Ray) Jones <thouis@gmail.com>2012-06-18 11:50:28 +0200
commit5b5a0f4999dfac66c9c27160737352c727a3517b (patch)
treedad10b0b30aa85ecb6093fd1017bebd13fb1a159 /tools/allocation_tracking/alloc_hook.pyx
parent32370937a5692befe4971790cc0b71f72fe08bb1 (diff)
downloadnumpy-5b5a0f4999dfac66c9c27160737352c727a3517b.tar.gz
Wrap hook functions with GIL, add example.
Wraps the SetHook and calls to the hook with the GIL, to prevent races. Adds an example of using the interface for callbacks into python code.
Diffstat (limited to 'tools/allocation_tracking/alloc_hook.pyx')
-rw-r--r--tools/allocation_tracking/alloc_hook.pyx42
1 files changed, 42 insertions, 0 deletions
diff --git a/tools/allocation_tracking/alloc_hook.pyx b/tools/allocation_tracking/alloc_hook.pyx
new file mode 100644
index 000000000..d1e656f90
--- /dev/null
+++ b/tools/allocation_tracking/alloc_hook.pyx
@@ -0,0 +1,42 @@
+# A cython wrapper for using python functions as callbacks for
+# PyDataMem_SetEventHook.
+
+cimport numpy as np
+
+cdef extern from "Python.h":
+ object PyLong_FromVoidPtr(void *)
+ void *PyLong_AsVoidPtr(object)
+
+ctypedef void PyDataMem_EventHookFunc(void *inp, void *outp, size_t size,
+ void *user_data)
+cdef extern from "numpy/arrayobject.h":
+ PyDataMem_EventHookFunc * \
+ PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook,
+ void *user_data, void **old_data)
+
+np.import_array()
+
+cdef void pyhook(void *old, void *new, size_t size, void *user_data):
+ cdef object pyfunc = <object> user_data
+ pyfunc(PyLong_FromVoidPtr(old),
+ PyLong_FromVoidPtr(new),
+ size)
+
+class NumpyAllocHook(object):
+ def __init__(self, callback):
+ self.callback = callback
+
+ def __enter__(self):
+ cdef void *old_hook, *old_data
+ old_hook = <void *> \
+ PyDataMem_SetEventHook(<PyDataMem_EventHookFunc *> pyhook,
+ <void *> self.callback,
+ <void **> &old_data)
+ self.old_hook = PyLong_FromVoidPtr(old_hook)
+ self.old_data = PyLong_FromVoidPtr(old_data)
+
+ def __exit__(self):
+ PyDataMem_SetEventHook(<PyDataMem_EventHookFunc *> \
+ PyLong_AsVoidPtr(self.old_hook),
+ <void *> PyLong_AsVoidPtr(self.old_data),
+ <void **> 0)