blob: b8fd841ca5db4bcb05f01973c254640738ea8fa5 [file] [log] [blame]
#include <Python.h>
#include "THP.h"
// Adapted from fblualib
void* ObjectPtrAllocator::malloc(long size) {
return allocator->malloc(allocatorContext, size);
}
void* ObjectPtrAllocator::realloc(void* ptr, long size) {
return allocator->realloc(allocatorContext, ptr, size);
}
void ObjectPtrAllocator::free(void* ptr) {
object.release();
allocator->free(allocatorContext, ptr);
delete this;
}
void StorageWeakRefAllocator::free(void* ptr) {
// All storage structs have the same structure and we just want to clear
// the cdata field. Setting cdata to NULL will prevent the object from
// calling free once more.
THPFloatStorage *storage = (THPFloatStorage*)object.get();
storage->cdata = nullptr;
object = nullptr;
allocator->free(allocatorContext, ptr);
delete this;
}
#ifdef WITH_NUMPY
void* NumpyArrayAllocator::realloc(void* ptr, long size) {
PyArrayObject *array_ptr = (PyArrayObject*)object.get();
if (array_ptr && ptr == PyArray_DATA(array_ptr)) {
void* newPtr = this->malloc(size);
memcpy(newPtr, ptr, std::min(size, PyArray_NBYTES(array_ptr)));
// Whee! We're done!
object = nullptr;
return newPtr;
}
return allocator->realloc(allocatorContext, ptr, size);
}
void NumpyArrayAllocator::free(void* ptr) {
PyArrayObject *array_ptr = (PyArrayObject*)object.get();
if (array_ptr && ptr == PyArray_DATA(array_ptr)) {
object = nullptr;
return;
}
allocator->free(allocatorContext, ptr);
delete this;
}
#endif
template<typename T>
static void * malloc_wrapper(void *ctx, long size) {
return ((T*)ctx)->malloc(size);
}
template<typename T>
static void * realloc_wrapper(void *ctx, void *ptr, long size) {
return ((T*)ctx)->realloc(ptr, size);
}
template<typename T>
static void free_wrapper(void *ctx, void *ptr) {
((T*)ctx)->free(ptr);
}
THAllocator THObjectPtrAllocator = {
malloc_wrapper<ObjectPtrAllocator>,
realloc_wrapper<ObjectPtrAllocator>,
free_wrapper<ObjectPtrAllocator>,
};
THAllocator THStorageWeakRefAllocator = {
malloc_wrapper<StorageWeakRefAllocator>,
realloc_wrapper<StorageWeakRefAllocator>,
free_wrapper<StorageWeakRefAllocator>,
};
#ifdef WITH_NUMPY
THAllocator THNumpyArrayAllocator = {
malloc_wrapper<NumpyArrayAllocator>,
realloc_wrapper<NumpyArrayAllocator>,
free_wrapper<NumpyArrayAllocator>,
};
#endif