solstice-solver

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

ssol_param_buffer.c (4332B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016, 2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "ssol.h"
     18 #include "ssol_device_c.h"
     19 
     20 #include <rsys/dynamic_array.h>
     21 #include <rsys/str.h>
     22 
     23 #define DEFAULT_ALIGNMENT 64
     24 
     25 struct param {
     26   void* mem;
     27   void (*release)(void*);
     28 };
     29 
     30 #define DARRAY_NAME param
     31 #define DARRAY_DATA struct param
     32 #include <rsys/dynamic_array.h>
     33 
     34 struct ssol_param_buffer {
     35   char* pool;
     36   size_t capacity;
     37   size_t size;
     38   struct darray_param params;
     39   ref_T ref;
     40   struct ssol_device* dev;
     41 };
     42 
     43 /*******************************************************************************
     44  * Helper functions
     45  ******************************************************************************/
     46 static void
     47 param_buffer_release(ref_T* ref)
     48 {
     49   struct ssol_param_buffer* buf;
     50   struct ssol_device* dev;
     51   ASSERT(ref);
     52   buf = CONTAINER_OF(ref, struct ssol_param_buffer, ref);
     53   SSOL(param_buffer_clear(buf));
     54   dev = buf->dev;
     55   if(buf->pool) MEM_RM(dev->allocator, buf->pool);
     56   darray_param_release(&buf->params);
     57   MEM_RM(dev->allocator, buf);
     58   SSOL(device_ref_put(dev));
     59 }
     60 
     61 /*******************************************************************************
     62  * Exported functions
     63  ******************************************************************************/
     64 res_T
     65 ssol_param_buffer_create
     66   (struct ssol_device* dev,
     67    const size_t capacity,
     68    struct ssol_param_buffer** out_buf)
     69 {
     70   struct ssol_param_buffer* buf = NULL;
     71   res_T res = RES_OK;
     72 
     73   if(!dev || !capacity || !out_buf) {
     74     res = RES_BAD_ARG;
     75     goto error;
     76   }
     77 
     78   buf = MEM_CALLOC(dev->allocator, 1, sizeof(struct ssol_param_buffer));
     79   if(!buf) {
     80     res = RES_MEM_ERR;
     81     goto error;
     82   }
     83   SSOL(device_ref_get(dev));
     84   buf->dev = dev;
     85   ref_init(&buf->ref);
     86   buf->capacity = capacity;
     87   buf->size = 0;
     88   darray_param_init(dev->allocator, &buf->params);
     89 
     90   buf->pool = MEM_ALLOC_ALIGNED(dev->allocator, capacity, DEFAULT_ALIGNMENT);
     91   if(!buf->pool) {
     92     res = RES_MEM_ERR;
     93     goto error;
     94   }
     95 
     96 exit:
     97   if(out_buf) *out_buf = buf;
     98   return res;
     99 error:
    100   if(buf) {
    101     SSOL(param_buffer_ref_put(buf));
    102     buf = NULL;
    103   }
    104   goto exit;
    105 }
    106 
    107 res_T
    108 ssol_param_buffer_ref_get(struct ssol_param_buffer* buf)
    109 {
    110   if(!buf) return RES_BAD_ARG;
    111   ref_get(&buf->ref);
    112   return RES_OK;
    113 }
    114 
    115 res_T
    116 ssol_param_buffer_ref_put(struct ssol_param_buffer* buf)
    117 {
    118   if(!buf) return RES_BAD_ARG;
    119   ref_put(&buf->ref, param_buffer_release);
    120   return RES_OK;
    121 }
    122 
    123 void*
    124 ssol_param_buffer_allocate
    125   (struct ssol_param_buffer* buf,
    126    const size_t size, /* In Bytes */
    127    const size_t align, /* Must be a power of 2 in [1, 64] */
    128    void (*release)(void*)) /* May be NULL */
    129 {
    130   struct param param = { NULL, NULL };
    131   size_t offset;
    132   res_T res = RES_OK;
    133 
    134   if(!buf || !size || !IS_POW2(align) || align > DEFAULT_ALIGNMENT)
    135     goto error;
    136 
    137   offset = ALIGN_SIZE(buf->size, align);
    138   if(offset + size > buf->capacity) goto error;
    139 
    140   param.mem = buf->pool + offset;
    141   param.release = release;
    142   ASSERT(IS_ALIGNED(param.mem, align));
    143 
    144   res = darray_param_push_back(&buf->params, &param);
    145   if(res != RES_OK) goto error;
    146 
    147   buf->size = offset + size;
    148 
    149 exit:
    150   return param.mem;
    151 error:
    152   param.mem = NULL;
    153   goto exit;
    154 }
    155 
    156 void*
    157 ssol_param_buffer_get(struct ssol_param_buffer* buf)
    158 {
    159   ASSERT(buf);
    160   return buf->size ? buf->pool : NULL;
    161 }
    162 
    163 res_T
    164 ssol_param_buffer_clear(struct ssol_param_buffer* buf)
    165 {
    166   size_t i;
    167   if(!buf) return RES_BAD_ARG;
    168 
    169   /* Release the parameter */
    170   FOR_EACH(i, 0, darray_param_size_get(&buf->params)) {
    171     struct param* param = darray_param_data_get(&buf->params)+i;
    172     if(param->release) param->release(param->mem);
    173   }
    174   darray_param_clear(&buf->params);
    175   buf->size = 0;
    176   return RES_OK;
    177 }
    178