commit 1ef0c178832b421e0d0ee96841192a24a54e1c70
parent 29f4a6343f61f97447fb12a82c8e020d4f07adbc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 3 Apr 2017 12:19:33 +0200
Update the ssol_param_buffer_allocate API
Add an optional "release" functor that once defined is invoked on the
allocated memory priorly to its destruction.
Diffstat:
3 files changed, 111 insertions(+), 31 deletions(-)
diff --git a/src/ssol.h b/src/ssol.h
@@ -852,7 +852,10 @@ SSOL_API void*
ssol_param_buffer_allocate
(struct ssol_param_buffer* buf,
const size_t size,
- const size_t alignment); /* Power of 2 in [1, 64] */
+ const size_t alignment, /* Power of 2 in [1, 64] */
+ /* Functor to invoke on the allocated memory priorly to its destruction.
+ * May be NULL */
+ void (*release)(void*));
/* Retrieve the address of the first allocated parameter */
SSOL_API void*
diff --git a/src/ssol_param_buffer.c b/src/ssol_param_buffer.c
@@ -22,15 +22,19 @@
#define DEFAULT_ALIGNMENT 64
struct param {
- size_t size; /* In Bytes */
- size_t offset; /* In Bytes */
+ void* mem;
+ void (*release)(void*);
};
+#define DARRAY_NAME param
+#define DARRAY_DATA struct param
+#include <rsys/dynamic_array.h>
+
struct ssol_param_buffer {
char* pool;
size_t capacity;
size_t size;
-
+ struct darray_param params;
ref_T ref;
struct ssol_device* dev;
};
@@ -45,8 +49,10 @@ param_buffer_release(ref_T* ref)
struct ssol_device* dev;
ASSERT(ref);
buf = CONTAINER_OF(ref, struct ssol_param_buffer, ref);
+ SSOL(param_buffer_clear(buf));
dev = buf->dev;
if(buf->pool) MEM_RM(dev->allocator, buf->pool);
+ darray_param_release(&buf->params);
MEM_RM(dev->allocator, buf);
SSOL(device_ref_put(dev));
}
@@ -78,6 +84,8 @@ ssol_param_buffer_create
ref_init(&buf->ref);
buf->capacity = capacity;
buf->size = 0;
+ darray_param_init(dev->allocator, &buf->params);
+
buf->pool = MEM_ALLOC_ALIGNED(dev->allocator, capacity, DEFAULT_ALIGNMENT);
if(!buf->pool) {
res = RES_MEM_ERR;
@@ -115,25 +123,32 @@ void*
ssol_param_buffer_allocate
(struct ssol_param_buffer* buf,
const size_t size, /* In Bytes */
- const size_t align) /* Must be a power of 2 in [1, 64] */
+ const size_t align, /* Must be a power of 2 in [1, 64] */
+ void (*release)(void*)) /* May be NULL */
{
+ struct param param = { NULL, NULL };
size_t offset;
- void* mem = NULL;
+ res_T res = RES_OK;
if(!buf || !size || !IS_POW2(align) || align > DEFAULT_ALIGNMENT)
goto error;
offset = ALIGN_SIZE(buf->size, align);
if(offset + size > buf->capacity) goto error;
-
- mem = buf->pool + offset;
- ASSERT(IS_ALIGNED(mem, align));
+
+ param.mem = buf->pool + offset;
+ param.release = release;
+ ASSERT(IS_ALIGNED(param.mem, align));
+
+ res = darray_param_push_back(&buf->params, ¶m);
+ if(res != RES_OK) goto error;
+
buf->size = offset + size;
exit:
- return mem;
+ return param.mem;
error:
- mem = NULL;
+ param.mem = NULL;
goto exit;
}
@@ -147,7 +162,15 @@ ssol_param_buffer_get(struct ssol_param_buffer* buf)
res_T
ssol_param_buffer_clear(struct ssol_param_buffer* buf)
{
+ size_t i;
if(!buf) return RES_BAD_ARG;
+
+ /* Release the parameter */
+ FOR_EACH(i, 0, darray_param_size_get(&buf->params)) {
+ struct param* param = darray_param_data_get(&buf->params)+i;
+ if(param->release) param->release(param->mem);
+ }
+ darray_param_clear(&buf->params);
buf->size = 0;
return RES_OK;
}
diff --git a/src/test_ssol_param_buffer.c b/src/test_ssol_param_buffer.c
@@ -19,18 +19,30 @@
#include <rsys/logger.h>
#include <limits.h>
+struct param {
+ char* name;
+ double d;
+ int i;
+ void* ptr;
+ struct ssol_image* img;
+};
+
+static void
+param_release(void* mem)
+{
+ struct param* param = mem;
+ ASSERT(param);
+ if(param->img) SSOL(image_ref_put(param->img));
+}
+
int
main(int argc, char** argv)
{
- struct param {
- char* name;
- double d;
- int i;
- void* ptr;
- }* param;
+ struct param* param;
struct mem_allocator allocator;
struct ssol_device* dev;
struct ssol_param_buffer* pbuf;
+ struct ssol_image* img;
size_t sz, al;
void* mem;
(void)argc, (void)argv;
@@ -53,14 +65,14 @@ main(int argc, char** argv)
sz = sizeof(intptr_t);
al = ALIGNOF(intptr_t);
- CHECK(mem = ssol_param_buffer_allocate(NULL, 0, 0), NULL);
- CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, 0), NULL);
- CHECK(mem = ssol_param_buffer_allocate(NULL, sz, 0), NULL);
- CHECK(mem = ssol_param_buffer_allocate(pbuf, sz, 0), NULL);
- CHECK(mem = ssol_param_buffer_allocate(NULL, 0, al), NULL);
- CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, al), NULL);
- CHECK(mem = ssol_param_buffer_allocate(NULL, sz, al), NULL);
- NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(NULL, 0, 0, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, 0, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(NULL, sz, 0, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(pbuf, sz, 0, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(NULL, 0, al, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(pbuf, 0, al, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(NULL, sz, al, NULL), NULL);
+ NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al, NULL), NULL);
*(intptr_t*)mem = 0xDECAFBAD;
CHECK(*(intptr_t*)ssol_param_buffer_get(pbuf), 0xDECAFBAD);
@@ -74,7 +86,7 @@ main(int argc, char** argv)
sz = strlen("Foo") + 1;
al = 4;
- NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al), NULL);
+ NCHECK(mem = ssol_param_buffer_allocate(pbuf, sz, al, NULL), NULL);
strcpy(mem, "Foo");
CHECK(strcmp(ssol_param_buffer_get(pbuf), "Foo"), 0);
strcpy(mem, "Bar");
@@ -85,12 +97,13 @@ main(int argc, char** argv)
sz = sizeof(struct param);
al = ALIGNOF(struct param);
- NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al), NULL);
- NCHECK(param->name = ssol_param_buffer_allocate(pbuf, 7, 64), NULL);
+ NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al, NULL), NULL);
+ NCHECK(param->name = ssol_param_buffer_allocate(pbuf, 7, 64, NULL), NULL);
strcpy(param->name, "0123456");
- NCHECK(param->ptr = ssol_param_buffer_allocate(pbuf, 4, 16), NULL);
+ NCHECK(param->ptr = ssol_param_buffer_allocate(pbuf, 4, 16, NULL), NULL);
param->d = PI;
param->i = -123;
+ param->img = NULL;
strcpy(param->ptr, "abc");
NCHECK(param = ssol_param_buffer_get(pbuf), NULL);
@@ -102,6 +115,46 @@ main(int argc, char** argv)
CHECK(strcmp(param->name, "0123456"), 0);
CHECK(strcmp(param->ptr, "abc"), 0);
+ CHECK(ssol_param_buffer_clear(pbuf), RES_OK);
+
+ sz = sizeof(struct param);
+ al = ALIGNOF(struct param);
+ CHECK(ssol_image_create(dev, &img), RES_OK);
+ CHECK(ssol_image_setup(img, 1280, 720, SSOL_PIXEL_DOUBLE3), RES_OK);
+ NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al, ¶m_release), NULL);
+ param->d = PI;
+ param->i = -123;
+ param->name = NULL;
+ param->ptr = NULL;
+ param->img = img;
+ CHECK(ssol_image_ref_get(img), RES_OK);
+
+ NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al, ¶m_release), NULL);
+ param->d = 123.456;
+ param->i = -1;
+ param->name = NULL;
+ param->ptr = NULL;
+ param->img = img;
+ CHECK(ssol_image_ref_get(img), RES_OK);
+
+ NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al, ¶m_release), NULL);
+ param->d = 0.1;
+ param->i = 789;
+ param->name = NULL;
+ param->ptr = NULL;
+ param->img = img;
+ CHECK(ssol_image_ref_get(img), RES_OK);
+
+ CHECK(ssol_param_buffer_clear(pbuf), RES_OK);
+
+ NCHECK(param = ssol_param_buffer_allocate(pbuf, sz, al, ¶m_release), NULL);
+ param->d = 0.1;
+ param->i = 789;
+ param->name = NULL;
+ param->ptr = NULL;
+ param->img = img;
+ CHECK(ssol_image_ref_get(img), RES_OK);
+
CHECK(ssol_param_buffer_ref_get(NULL), RES_BAD_ARG);
CHECK(ssol_param_buffer_ref_get(pbuf), RES_OK);
CHECK(ssol_param_buffer_ref_put(NULL), RES_BAD_ARG);
@@ -109,9 +162,10 @@ main(int argc, char** argv)
CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK);
CHECK(ssol_param_buffer_create(dev, 8, &pbuf), RES_OK);
- NCHECK(mem = ssol_param_buffer_allocate(pbuf, 2, 1), NULL);
- CHECK(mem = ssol_param_buffer_allocate(pbuf, 1, 16), NULL);
+ NCHECK(mem = ssol_param_buffer_allocate(pbuf, 2, 1, NULL), NULL);
+ CHECK(mem = ssol_param_buffer_allocate(pbuf, 1, 16, NULL), NULL);
+ CHECK(ssol_image_ref_put(img), RES_OK);
CHECK(ssol_param_buffer_ref_put(pbuf), RES_OK);
CHECK(ssol_device_ref_put(dev), RES_OK);