mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
Add caching of freed memories to the allocator
Memories might be freed outside the pool if the buffer was copied and the copy is freed after the original buffer. Caching up to 8 freed memories makes it possible to recycle these memories in most cases.
This commit is contained in:
parent
6490e853fd
commit
2d13fb16e8
2 changed files with 62 additions and 9 deletions
|
@ -494,6 +494,11 @@ typedef struct {
|
|||
guint8 *data;
|
||||
} GstAjaMemory;
|
||||
|
||||
typedef struct {
|
||||
guint8 *data;
|
||||
gsize size;
|
||||
} FreedMemory;
|
||||
|
||||
G_DEFINE_TYPE(GstAjaAllocator, gst_aja_allocator, GST_TYPE_ALLOCATOR);
|
||||
|
||||
static inline void _aja_memory_init(GstAjaAllocator *alloc, GstAjaMemory *mem,
|
||||
|
@ -524,14 +529,35 @@ static GstAjaMemory *_aja_memory_new_block(GstAjaAllocator *alloc,
|
|||
GstMemoryFlags flags, gsize maxsize,
|
||||
gsize offset, gsize size) {
|
||||
GstAjaMemory *mem;
|
||||
guint8 *data;
|
||||
guint8 *data = NULL;
|
||||
|
||||
mem = (GstAjaMemory *)g_new0(GstAjaMemory, 1);
|
||||
|
||||
data = (guint8 *)AJAMemory::AllocateAligned(maxsize, 4096);
|
||||
GST_TRACE_OBJECT(alloc, "Allocated %" G_GSIZE_FORMAT " at %p", maxsize, data);
|
||||
if (!alloc->device->device->DMABufferLock((ULWord *)data, maxsize, true)) {
|
||||
GST_WARNING_OBJECT(alloc, "Failed to pre-lock memory");
|
||||
GST_OBJECT_LOCK(alloc);
|
||||
guint n = gst_queue_array_get_length(alloc->freed_mems);
|
||||
for (guint i = 0; i < n; i++) {
|
||||
FreedMemory *fmem =
|
||||
(FreedMemory *)gst_queue_array_peek_nth_struct(alloc->freed_mems, i);
|
||||
|
||||
if (fmem->size == size) {
|
||||
data = fmem->data;
|
||||
GST_TRACE_OBJECT(
|
||||
alloc, "Using cached freed memory of size %" G_GSIZE_FORMAT " at %p",
|
||||
fmem->size, fmem->data);
|
||||
gst_queue_array_drop_struct(alloc->freed_mems, i, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
GST_OBJECT_UNLOCK(alloc);
|
||||
|
||||
if (!data) {
|
||||
data = (guint8 *)AJAMemory::AllocateAligned(maxsize, 4096);
|
||||
GST_TRACE_OBJECT(alloc,
|
||||
"Allocated memory of size %" G_GSIZE_FORMAT " at %p",
|
||||
maxsize, data);
|
||||
if (!alloc->device->device->DMABufferLock((ULWord *)data, maxsize, true)) {
|
||||
GST_WARNING_OBJECT(alloc, "Failed to pre-lock memory");
|
||||
}
|
||||
}
|
||||
|
||||
_aja_memory_init(alloc, mem, flags, NULL, data, maxsize, offset, size);
|
||||
|
@ -598,10 +624,27 @@ static void gst_aja_allocator_free(GstAllocator *alloc, GstMemory *mem) {
|
|||
if (!mem->parent) {
|
||||
GstAjaAllocator *aja_alloc = GST_AJA_ALLOCATOR(alloc);
|
||||
|
||||
GST_TRACE_OBJECT(alloc, "Freeing memory at %p", dmem->data);
|
||||
aja_alloc->device->device->DMABufferUnlock((ULWord *)dmem->data,
|
||||
mem->maxsize);
|
||||
AJAMemory::FreeAligned(dmem->data);
|
||||
GST_OBJECT_LOCK(aja_alloc);
|
||||
while (gst_queue_array_get_length(aja_alloc->freed_mems) > 8) {
|
||||
FreedMemory *fmem =
|
||||
(FreedMemory *)gst_queue_array_pop_head_struct(aja_alloc->freed_mems);
|
||||
|
||||
GST_TRACE_OBJECT(
|
||||
alloc, "Freeing cached memory of size %" G_GSIZE_FORMAT " at %p",
|
||||
fmem->size, fmem->data);
|
||||
aja_alloc->device->device->DMABufferUnlock((ULWord *)fmem->data,
|
||||
fmem->size);
|
||||
AJAMemory::FreeAligned(fmem->data);
|
||||
}
|
||||
|
||||
FreedMemory fmem;
|
||||
GST_TRACE_OBJECT(alloc,
|
||||
"Caching freed memory of size %" G_GSIZE_FORMAT " at %p",
|
||||
mem->maxsize, dmem->data);
|
||||
fmem.data = dmem->data;
|
||||
fmem.size = mem->size;
|
||||
gst_queue_array_push_tail_struct(aja_alloc->freed_mems, &fmem);
|
||||
GST_OBJECT_UNLOCK(aja_alloc);
|
||||
}
|
||||
|
||||
g_free(dmem);
|
||||
|
@ -612,6 +655,14 @@ static void gst_aja_allocator_finalize(GObject *alloc) {
|
|||
|
||||
GST_DEBUG_OBJECT(alloc, "Freeing allocator");
|
||||
|
||||
FreedMemory *mem;
|
||||
while ((mem = (FreedMemory *)gst_queue_array_pop_head_struct(
|
||||
aja_alloc->freed_mems))) {
|
||||
GST_TRACE_OBJECT(alloc, "Freeing cached memory at %p", mem->data);
|
||||
aja_alloc->device->device->DMABufferUnlock((ULWord *)mem->data, mem->size);
|
||||
AJAMemory::FreeAligned(mem->data);
|
||||
}
|
||||
|
||||
gst_aja_ntv2_device_unref(aja_alloc->device);
|
||||
|
||||
G_OBJECT_CLASS(gst_aja_allocator_parent_class)->finalize(alloc);
|
||||
|
@ -645,6 +696,7 @@ GstAllocator *gst_aja_allocator_new(GstAjaNtv2Device *device) {
|
|||
(GstAjaAllocator *)g_object_new(GST_TYPE_AJA_ALLOCATOR, NULL);
|
||||
|
||||
alloc->device = gst_aja_ntv2_device_ref(device);
|
||||
alloc->freed_mems = gst_queue_array_new_for_struct(sizeof(FreedMemory), 16);
|
||||
|
||||
GST_DEBUG_OBJECT(alloc, "Creating allocator for device %d",
|
||||
device->device->GetIndexNumber());
|
||||
|
|
|
@ -91,6 +91,7 @@ struct _GstAjaAllocator {
|
|||
GstAllocator allocator;
|
||||
|
||||
GstAjaNtv2Device *device;
|
||||
GstQueueArray *freed_mems;
|
||||
};
|
||||
|
||||
struct _GstAjaAllocatorClass {
|
||||
|
|
Loading…
Reference in a new issue