1#------------------------------------------------------------------------------ 2 3cdef extern from "Python.h": 4 enum: PY_SSIZE_T_MAX 5 void *PyMem_Malloc(size_t) 6 void *PyMem_Calloc(size_t, size_t) 7 void *PyMem_Realloc(void*, size_t) 8 void PyMem_Free(void*) 9 10cdef extern from * nogil: 11 """ 12 #if PY_VERSION_HEX < 0x03050000 13 # define PyMPI_RawMalloc(n) malloc((n)?(n):1) 14 # define PyMPI_RawCalloc(n,s) ((n)&&(s))?calloc((n),(s)):calloc(1,1) 15 # define PyMPI_RawRealloc(p,n) realloc((p),(n)?(n):1)) 16 # define PyMPI_RawFree free 17 #else 18 # define PyMPI_RawMalloc PyMem_RawMalloc 19 # define PyMPI_RawCalloc PyMem_RawCalloc 20 # define PyMPI_RawRealloc PyMem_RawRealloc 21 # define PyMPI_RawFree PyMem_RawFree 22 #endif 23 """ 24 void *PyMPI_RawMalloc(size_t) 25 void *PyMPI_RawCalloc(size_t, size_t) 26 void *PyMPI_RawRealloc(void*, size_t) 27 void PyMPI_RawFree(void*) 28 29#------------------------------------------------------------------------------ 30 31@cython.final 32@cython.internal 33cdef class _p_mem: 34 cdef void *buf 35 cdef size_t len 36 cdef void (*free)(void*) 37 def __cinit__(self): 38 self.buf = NULL 39 self.len = 0 40 self.free = NULL 41 def __dealloc__(self): 42 if self.free: 43 self.free(self.buf) 44 45 46cdef inline _p_mem allocate(Py_ssize_t m, size_t b, void *buf): 47 if m > PY_SSIZE_T_MAX/<Py_ssize_t>b: 48 raise MemoryError("memory allocation size too large") 49 if m < 0: 50 raise RuntimeError("memory allocation with negative size") 51 cdef _p_mem ob = _p_mem.__new__(_p_mem) 52 ob.len = <size_t>m * b 53 ob.free = PyMem_Free 54 ob.buf = PyMem_Malloc(<size_t>m * b) 55 if ob.buf == NULL: raise MemoryError 56 if buf != NULL: (<void**>buf)[0] = ob.buf 57 return ob 58 59 60cdef inline _p_mem rawalloc(Py_ssize_t m, size_t b, bint clear, void *buf): 61 if m > PY_SSIZE_T_MAX/<Py_ssize_t>b: 62 raise MemoryError("memory allocation size too large") 63 if m < 0: 64 raise RuntimeError("memory allocation with negative size") 65 cdef _p_mem ob = _p_mem.__new__(_p_mem) 66 ob.len = <size_t>m * b 67 ob.free = PyMPI_RawFree 68 if clear: 69 ob.buf = PyMPI_RawCalloc(<size_t>m, b) 70 else: 71 ob.buf = PyMPI_RawMalloc(<size_t>m * b) 72 if ob.buf == NULL: raise MemoryError 73 if buf != NULL: (<void**>buf)[0] = ob.buf 74 return ob 75 76#------------------------------------------------------------------------------ 77