diff options
Diffstat (limited to 'source/blender/blenlib/intern/BLI_mempool.c')
-rw-r--r-- | source/blender/blenlib/intern/BLI_mempool.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c index d98e63d88dd..5f0c90f234d 100644 --- a/source/blender/blenlib/intern/BLI_mempool.c +++ b/source/blender/blenlib/intern/BLI_mempool.c @@ -27,9 +27,7 @@ /** \file blender/blenlib/intern/BLI_mempool.c * \ingroup bli - */ - -/* + * * Simple, fast memory allocator for allocating many elements of the same size. */ @@ -56,6 +54,9 @@ #define FREEWORD MAKE_ID('f', 'r', 'e', 'e') +/* currently totalloc isnt used */ +// #define USE_TOTALLOC + typedef struct BLI_freenode { struct BLI_freenode *next; int freeword; /* used to identify this as a freed node */ @@ -112,6 +113,7 @@ BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag) pool->pchunk = pchunk; pool->csize = esize * pchunk; pool->chunks.first = pool->chunks.last = NULL; + pool->totalloc = 0; pool->totused = 0; maxchunks = totelem / pchunk + 1; @@ -161,10 +163,11 @@ BLI_mempool *BLI_mempool_create(int esize, int totelem, int pchunk, int flag) } } - /* set the end of this chunks memoryy to the new tail for next iteration */ + /* set the end of this chunks memory to the new tail for next iteration */ lasttail = curnode; - +#ifdef USE_TOTALLOC pool->totalloc += pool->pchunk; +#endif } /* terminate the list */ curnode->next = NULL; @@ -215,8 +218,9 @@ void *BLI_mempool_alloc(BLI_mempool *pool) } } curnode->next = NULL; /* terminate the list */ - +#ifdef USE_TOTALLOC pool->totalloc += pool->pchunk; +#endif } retval = pool->free; @@ -237,12 +241,20 @@ void *BLI_mempool_calloc(BLI_mempool *pool) return retval; } -/* doesnt protect against double frees, don't be stupid! */ +/** + * Free an element from the mempool. + * + * \note doesnt protect against double frees, don't be stupid! + */ void BLI_mempool_free(BLI_mempool *pool, void *addr) { BLI_freenode *newhead = addr; if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) { +#ifndef NDEBUG + /* this will detect double free's */ + BLI_assert(newhead->freeword != FREEWORD); +#endif newhead->freeword = FREEWORD; } @@ -276,7 +288,9 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr) } BLI_addtail(&pool->chunks, first); +#ifdef USE_TOTALLOC pool->totalloc = pool->pchunk; +#endif pool->free = first->data; /* start of the list */ for (tmpaddr = first->data, i = 0; i < pool->pchunk; i++) { @@ -295,33 +309,51 @@ int BLI_mempool_count(BLI_mempool *pool) void *BLI_mempool_findelem(BLI_mempool *pool, int index) { - if (!(pool->flag & BLI_MEMPOOL_ALLOW_ITER)) { - fprintf(stderr, "%s: Error! you can't iterate over this mempool!\n", __func__); - return NULL; - } - else if ((index >= 0) && (index < pool->totused)) { + BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); + + if ((index >= 0) && (index < pool->totused)) { /* we could have some faster mem chunk stepping code inline */ BLI_mempool_iter iter; void *elem; BLI_mempool_iternew(pool, &iter); for (elem = BLI_mempool_iterstep(&iter); index-- != 0; elem = BLI_mempool_iterstep(&iter)) { /* do nothing */ - }; + } return elem; } return NULL; } -void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) +/** + * \param data array of pointers at least the size of 'pool->totused' + */ +void BLI_mempool_as_array(BLI_mempool *pool, void **data) { - if (!(pool->flag & BLI_MEMPOOL_ALLOW_ITER)) { - fprintf(stderr, "%s: Error! you can't iterate over this mempool!\n", __func__); - iter->curchunk = NULL; - iter->curindex = 0; - - return; + BLI_mempool_iter iter; + void *elem; + void **p = data; + BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); + BLI_mempool_iternew(pool, &iter); + for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) { + *p++ = elem; } + BLI_assert((p - data) == pool->totused); +} + +/** + * Allocate an array from the mempool. + */ +void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr) +{ + void *data = MEM_mallocN(BLI_mempool_count(pool) * pool->esize, allocstr); + BLI_mempool_as_array(pool, data); + return data; +} + +void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) +{ + BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER); iter->pool = pool; iter->curchunk = pool->chunks.first; @@ -391,6 +423,9 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter) #endif +/** + * Free the mempool its self (and all elements). + */ void BLI_mempool_destroy(BLI_mempool *pool) { BLI_mempool_chunk *mpchunk = NULL; |