solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

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:
Msrc/ssol.h | 5++++-
Msrc/ssol_param_buffer.c | 43+++++++++++++++++++++++++++++++++----------
Msrc/test_ssol_param_buffer.c | 94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
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, &param); + 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, &param_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, &param_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, &param_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, &param_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);