Commit b8eb6545 authored by Stefan Behnel's avatar Stefan Behnel

reuse pre-allocated thread locks in critical memoryview creation path

parent a0a3cb4b
......@@ -300,6 +300,24 @@ cdef void *align_pointer(void *memory, size_t alignment) nogil:
return <void *> aligned_p
# pre-allocate thread locks for reuse
## note that this could be implemented in a more beautiful way in "normal" Cython,
## but this code gets merged into the user module and not everything works there.
DEF THREAD_LOCKS_PREALLOCATED = 8
cdef int _thread_locks_used = 0
cdef PyThread_type_lock[THREAD_LOCKS_PREALLOCATED] _thread_locks = [
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
PyThread_allocate_lock(),
]
@cname('__pyx_memoryview')
cdef class memoryview(object):
......@@ -325,8 +343,13 @@ cdef class memoryview(object):
(<__pyx_buffer *> &self.view).obj = Py_None
Py_INCREF(Py_None)
global _thread_locks_used
if _thread_locks_used < THREAD_LOCKS_PREALLOCATED:
self.lock = _thread_locks[_thread_locks_used]
_thread_locks_used += 1
if self.lock is NULL:
self.lock = PyThread_allocate_lock()
if self.lock == NULL:
if self.lock is NULL:
raise MemoryError
if flags & PyBUF_FORMAT:
......@@ -342,7 +365,17 @@ cdef class memoryview(object):
if self.obj is not None:
__Pyx_ReleaseBuffer(&self.view)
cdef int i
global _thread_locks_used
if self.lock != NULL:
for i in range(_thread_locks_used):
if _thread_locks[i] is self.lock:
_thread_locks_used -= 1
if i != _thread_locks_used:
_thread_locks[i], _thread_locks[_thread_locks_used] = (
_thread_locks[_thread_locks_used], _thread_locks[i])
break
else:
PyThread_free_lock(self.lock)
cdef char *get_item_pointer(memoryview self, object index) except NULL:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment