Closed EmilioPeJu closed 6 months ago
Just let you know that I finished the initial implementation of the AD plugin relying on this feature, it's in https://github.com/dls-controls/ADExternal
From what it looks like, the changes in this PR will work for what they were intended. However, I believe we already put in place a more general set of interfaces that would allow one to do this (the four methods starting with https://github.com/areaDetector/ADCore/blob/master/ADApp/ADSrc/NDArrayPool.cpp#L56). In the APS DAQ software we have a separate pool class for each type of DAQ object that we need to create and manage (see, for example, https://git.aps.anl.gov/C2/daq/modules/daq-base/-/blob/master/src/pva/daq/pva/PvaNDArrayPool.h#L55). This allows us to use AD framework with our own objects that inherit from NDArray.
The thing is ... making a subclass of NDArrayPool
would only affect the the plugin instantiating it, and the usual case is not even that, because NDPluginDriver::driverCallback
sets this->pNDArrayPool = pArray->pNDArrayPool
, which means it uses the NDArrayPool
of the original source of the frame.
For my application, I needed to force the source of the frames to use shared memory, the way I proposed will force every plugin and driver to use shared memory and that way my plugin can get frames from anywhere.
@sveseli , unfortunately, I don't have access permission for your link, I assume the buffers allocated by your NDArrayPool
subclass were also coming from malloc
which limits the applications, if not, how did you workaround the free
call inside NDArrayPool::alloc
?
@MarkRivers , this is a different problem right? in your case, you want to use special allocation only for the output frame of one plugin, not for everything. It's also an interesting problem, so let's brainstorm a few solutions:
NDArrayPool::alloc
and NDArrayPool::release
be virtual functions, however, the subclass that overrides one, should override the other one too, or they would be inconsistent. I suspect this approach is not desirable as we might want to force caching of free frames (in freeList
) for a faster allocation.NDArrayPool::createArray
returning a frame with populated pData
, which is similar to passing pData
to NDArrayPool::alloc
but it kind of assume that it was allocated using malloc
and at some point it will free it using free
.NDArrayPool::onAllocateArray
don't seem to help for this, as they get called too lateNDArray
and make NDArrayPool::alloc
use those (when they are not NULL
), instead of malloc/free... the pointers would possibly be set inside an overridden NDArrayPool::createArray
NDArrayPool::alloc
, this is not desirable because we would need to change every place where it gets called.@EmilioPeJu , if you'd like, we could probably get you read access to APS DAQ repositories, just send me email.
In our case, we do not really use internal NDArray buffer, but instead create our own objects that are destroyed when the delete is called. The IOC driver instantiates the appropriate pool class, not individual plugins (see, for example https://git.aps.anl.gov/C2/daq/iocs/daq-ps-ioc/-/blob/master/src/driver/PsDaqDriver.cpp?ref_type=heads#L339).
Looking at the NDArrayPool code again, I think you are right, there should be additional hooks that that would hide malloc/free calls.
OK, I've amended my commit and provided a hook to locally override the frame buffer allocation and deallocation functions.
The functions that you would override in a subclass are frameMalloc
and frameFree
.
I still keep the function to override the default malloc and free functions (which I need) but now I've made the setter function a static method of NDArrayPool
called setDefaultFrameMemoryFunctions
. I've also renamed a few things to be consistent with the rest and I hope the code looks cleaner now.
See issue https://github.com/areaDetector/ADCore/issues/487