ucx/mempool.c

Wed, 27 Feb 2013 13:30:21 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 27 Feb 2013 13:30:21 +0100
changeset 95
ecfdc1c4a552
parent 75
990734f548ef
child 103
08018864fb91
permissions
-rw-r--r--

added gnu++11 support

     1 /*
     2  *
     3  */
     5 #include <stdlib.h>
     6 #include <string.h>
     7 #include <stdio.h>
     8 #ifdef __cplusplus
     9 #define __STDC_FORMAT_MACROS
    10 #endif
    11 #include <inttypes.h>
    13 #include "mempool.h"
    15 typedef struct {
    16     ucx_destructor destructor;
    17     char c;
    18 } ucx_memchunk;
    20 typedef struct {
    21     ucx_destructor destructor;
    22     void           *ptr;
    23 } ucx_regdestr;
    25 void ucx_mempool_shared_destr(void* ptr) {
    26     ucx_regdestr *rd = (ucx_regdestr*)ptr;
    27     rd->destructor(rd->ptr);
    28 }
    30 UcxMempool *ucx_mempool_new(size_t n) {
    31     UcxMempool *pool = (UcxMempool*)malloc(sizeof(UcxMempool));
    32     if (pool == NULL) return NULL;
    34     pool->data = (void**) malloc(n * sizeof(void*));
    35     if (pool->data == NULL) {
    36         free(pool);
    37         return NULL;
    38     }
    40     pool->ndata = 0;
    41     pool->size = n;
    42     return pool;
    43 }
    45 int ucx_mempool_chcap(UcxMempool *pool, size_t newcap) {
    46     void **data = (void**) realloc(pool->data, newcap*sizeof(void*));
    47     if (data == NULL) {
    48         return 1;
    49     } else {
    50         pool->data = data; 
    51         pool->size = newcap;
    52         return EXIT_SUCCESS;
    53     }
    54 }
    56 void *ucx_mempool_malloc(UcxMempool *pool, size_t n) {
    57     ucx_memchunk *mem = (ucx_memchunk*)malloc(sizeof(ucx_destructor) + n);
    58     if (mem == NULL) return NULL;
    60     if (pool->ndata >= pool->size) {
    61         ucx_mempool_chcap(pool, pool->size + 16);
    62      }
    64     mem->destructor = NULL;
    65     pool->data[pool->ndata] = mem;
    66     pool->ndata++;
    68     return &mem->c;
    69 }
    71 void *ucx_mempool_calloc(UcxMempool *pool, size_t nelem, size_t elsize) {
    72     void *ptr = ucx_mempool_malloc(pool, nelem*elsize);
    73     if(ptr == NULL) {
    74         return NULL;
    75     }
    76     memset(ptr, 0, nelem * elsize);
    77     return ptr;
    78 }
    80 void *ucx_mempool_realloc(UcxMempool *pool, void *ptr, size_t n) {
    81     char *mem = ((char*)ptr) - sizeof(ucx_destructor);
    82     char *newm = (char*) realloc(mem, n + sizeof(ucx_destructor));
    83     if (newm == NULL) return NULL;
    84     if (mem != newm) {
    85         for(size_t i=0 ; i < pool->ndata ; i++) {
    86             if(pool->data[i] == mem) {
    87                 pool->data[i] = newm;
    88                 return newm + sizeof(ucx_destructor);
    89             }
    90         }
    91         fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
    92           (intptr_t)ptr, (intptr_t)pool);
    93         exit(1);
    94     } else {
    95         return newm + sizeof(ucx_destructor);
    96     }
    97 }
    99 void ucx_mempool_free(UcxMempool *pool) {
   100     ucx_memchunk *chunk;
   101     for(size_t i=0 ; i<pool->ndata ; i++) {
   102         chunk = (ucx_memchunk*) pool->data[i];
   103         if(chunk->destructor != NULL) {
   104             chunk->destructor(&chunk->c);
   105         }
   106         free(chunk);
   107     }
   108     free(pool->data);
   109     free(pool);
   110 }
   112 void ucx_mempool_set_destr(void *ptr, ucx_destructor func) {
   113     *(ucx_destructor*)((char*)ptr-sizeof(ucx_destructor)) = func;
   114 }
   116 void ucx_mempool_reg_destr(UcxMempool *pool, void *ptr, ucx_destructor destr) {
   117     ucx_regdestr *rd = (ucx_regdestr*)ucx_mempool_malloc(
   118             pool,
   119             sizeof(ucx_regdestr));
   120     rd->destructor = destr;
   121     rd->ptr = ptr;
   122     ucx_mempool_set_destr(rd, ucx_mempool_shared_destr);
   123 }

mercurial