* very simplistic small memory block cache to avoid more expensive libc * allocations * base function for data cache with 1 byte buckets and dimension cache with * sizeof(npy_intp) byte buckets */
| 89 | * sizeof(npy_intp) byte buckets |
| 90 | */ |
| 91 | static inline void * |
| 92 | _npy_alloc_cache(npy_uintp nelem, npy_uintp esz, npy_uint msz, |
| 93 | cache_bucket * cache, void * (*alloc)(size_t)) |
| 94 | { |
| 95 | void * p; |
| 96 | assert((esz == 1 && cache == datacache) || |
| 97 | (esz == sizeof(npy_intp) && cache == dimcache)); |
| 98 | assert(PyGILState_Check()); |
| 99 | if (nelem < msz) { |
| 100 | if (cache[nelem].available > 0) { |
| 101 | return cache[nelem].ptrs[--(cache[nelem].available)]; |
| 102 | } |
| 103 | } |
| 104 | p = alloc(nelem * esz); |
| 105 | if (p) { |
| 106 | #ifdef _PyPyGC_AddMemoryPressure |
| 107 | _PyPyPyGC_AddMemoryPressure(nelem * esz); |
| 108 | #endif |
| 109 | #ifdef NPY_OS_LINUX |
| 110 | /* allow kernel allocating huge pages for large arrays */ |
| 111 | if (NPY_UNLIKELY(nelem * esz >= ((1u<<22u))) && _madvise_hugepage) { |
| 112 | npy_uintp offset = 4096u - (npy_uintp)p % (4096u); |
| 113 | npy_uintp length = nelem * esz - offset; |
| 114 | /** |
| 115 | * Intentionally not checking for errors that may be returned by |
| 116 | * older kernel versions; optimistically tries enabling huge pages. |
| 117 | */ |
| 118 | madvise((void*)((npy_uintp)p + offset), length, MADV_HUGEPAGE); |
| 119 | } |
| 120 | #endif |
| 121 | } |
| 122 | return p; |
| 123 | } |
| 124 | |
| 125 | /* |
| 126 | * return pointer p to cache, nelem is number of elements of the cache bucket |
no outgoing calls
no test coverage detected