Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a way to override memory allocator for frames #486

Merged
merged 1 commit into from
Jan 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions ADApp/ADSrc/NDArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ NDArray::NDArray(int nDims, size_t *dims, NDDataType_t dataType, size_t dataSize
if (pData) {
this->pData = pData;
} else {
this->pData = malloc(dataSize);
this->pData = defaultFrameMalloc(dataSize);
this->dataSize = dataSize;
}
}
Expand All @@ -73,7 +73,12 @@ NDArray::NDArray(int nDims, size_t *dims, NDDataType_t dataType, size_t dataSize
* Frees the data array, deletes all attributes, frees the attribute list and destroys the mutex. */
NDArray::~NDArray()
{
if (this->pData) free(this->pData);
if (this->pData) {
if (this->pNDArrayPool)
this->pNDArrayPool->frameFree(this->pData);
else
defaultFrameFree(this->pData);
}
delete this->pAttributeList;
}

Expand Down
9 changes: 9 additions & 0 deletions ADApp/ADSrc/NDArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
/** The maximum number of dimensions in an NDArray */
#define ND_ARRAY_MAX_DIMS 10

typedef void *(*MallocFunc_t)(size_t size);
typedef void (*FreeFunc_t)(void *ptr);
extern MallocFunc_t defaultFrameMalloc;
extern FreeFunc_t defaultFrameFree;

/** Enumeration of color modes for NDArray attribute "colorMode" */
typedef enum
{
Expand Down Expand Up @@ -182,6 +187,10 @@ class ADCORE_API NDArrayPool {
size_t getMemorySize();
int getNumFree();
void emptyFreeList();
static void setDefaultFrameMemoryFunctions(MallocFunc_t newMalloc,
FreeFunc_t newFree);
virtual void* frameMalloc(size_t size);
virtual void frameFree(void *ptr);

protected:
/** The following methods should be implemented by a pool class
Expand Down
43 changes: 41 additions & 2 deletions ADApp/ADSrc/NDArrayPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

static const char *driverName = "NDArrayPool";

// This provides a way of overriding the default memory functions for frame
// buffer allocation and freeing
MallocFunc_t defaultFrameMalloc = malloc;
FreeFunc_t defaultFrameFree = free;

/** eraseNDAttributes is a global flag the controls whether NDArray::clearAttributes() is called
* each time a new array is allocated with NDArrayPool->alloc().
Expand All @@ -53,6 +57,41 @@ NDArrayPool::NDArrayPool(class asynNDArrayDriver *pDriver, size_t maxMemory)
listLock_ = epicsMutexCreate();
}

/** Set default frame buffer allocation and deallocation functions
* \param[in] newMalloc Pointer to a function that will be used by default to
* allocate a frame buffer
* \param[in] newFree Pointer to a function that will be used by default to
* deallocate a frame buffer
* **/
void NDArrayPool::setDefaultFrameMemoryFunctions(
MallocFunc_t newMalloc, FreeFunc_t newFree)
{
if (newMalloc)
defaultFrameMalloc = newMalloc;

if (newFree)
defaultFrameFree = newFree;
}

/** Used to allocate a frame buffer
* This method can be overriden in subclasses to use custom memory allocation
* \param[in] size Required buffer size
* Returns pointer to buffer of size specified
*/
void* NDArrayPool::frameMalloc(size_t size)
{
return defaultFrameMalloc(size);
}

/** Used to free a frame buffer
* This method can be overriden in subclasses to use custom memory deallocation
* \param[in] ptr Pointer to memory that will be deallocated
*/
void NDArrayPool::frameFree(void *ptr)
{
defaultFrameFree(ptr);
}

/** Create new NDArray object.
* This method should be overriden by a pool class that manages objects
* that derive from NDArray class.
Expand Down Expand Up @@ -139,7 +178,7 @@ NDArray* NDArrayPool::alloc(int ndims, size_t *dims, NDDataType_t dataType, size
if (pData || (pListElement->dataSize_ > (dataSize * THRESHOLD_SIZE_RATIO))) {
// We found an array but it is too large. Set the size to 0 so it will be allocated below.
memorySize_ -= pArray->dataSize;
free(pArray->pData);
frameFree(pArray->pData);
pArray->pData = NULL;
}
freeList_.erase(pListElement);
Expand Down Expand Up @@ -193,7 +232,7 @@ NDArray* NDArrayPool::alloc(int ndims, size_t *dims, NDDataType_t dataType, size
"%s: error: reached limit of %ld memory (%d buffers)\n",
functionName, (long)maxMemory_, numBuffers_);
} else {
pArray->pData = malloc(dataSize);
pArray->pData = frameMalloc(dataSize);
if (pArray->pData) {
pArray->dataSize = dataSize;
pArray->compressedSize = dataSize;
Expand Down
Loading