diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-08-20 20:56:46 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-08-20 20:56:46 +0400 |
commit | 65edd07edf270999cc5a59bf4bc732fd1ff56119 (patch) | |
tree | 48c2a8153cd608a1227694acd2c596d2899e21c7 | |
parent | b1a0dc6630008286ce957501cd52e29fb57199c6 (diff) |
add BLI_memarena_clear function to reset a memarena, keeping the last allocated block for more efficient reuse.
-rw-r--r-- | source/blender/blenlib/BLI_memarena.h | 10 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_memarena.c | 49 |
2 files changed, 49 insertions, 10 deletions
diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h index d54dab42e05..fbcacf515b5 100644 --- a/source/blender/blenlib/BLI_memarena.h +++ b/source/blender/blenlib/BLI_memarena.h @@ -93,10 +93,14 @@ __attribute__((alloc_size(2))) #endif ; -#ifdef __cplusplus -} +void BLI_memarena_clear(MemArena *ma) +#if MEM_GNU_ATTRIBUTES +__attribute__((nonnull(1))) #endif +; - +#ifdef __cplusplus +} #endif +#endif /* __BLI_MEMARENA_H__ */ diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c index ef10cb805ad..7fe5607a24e 100644 --- a/source/blender/blenlib/intern/BLI_memarena.c +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -30,6 +30,8 @@ * \ingroup bli */ +#include <string.h> + #include "MEM_guardedalloc.h" #include "BLI_memarena.h" @@ -89,6 +91,16 @@ void BLI_memarena_free(MemArena *ma) /* amt must be power of two */ #define PADUP(num, amt) (((num) + ((amt) - 1)) & ~((amt) - 1)) +/* align alloc'ed memory (needed if align > 8) */ +static void memarena_curbuf_align(MemArena *ma) +{ + unsigned char *tmp; + + tmp = (unsigned char *)PADUP( (intptr_t) ma->curbuf, ma->align); + ma->cursize -= (int)(tmp - ma->curbuf); + ma->curbuf = tmp; +} + void *BLI_memarena_alloc(MemArena *ma, int size) { void *ptr; @@ -98,8 +110,6 @@ void *BLI_memarena_alloc(MemArena *ma, int size) size = PADUP(size, ma->align); if (size > ma->cursize) { - unsigned char *tmp; - if (size > ma->bufsize - (ma->align - 1)) { ma->cursize = PADUP(size + 1, ma->align); } @@ -112,11 +122,7 @@ void *BLI_memarena_alloc(MemArena *ma, int size) ma->curbuf = MEM_mallocN((size_t)ma->cursize, ma->name); BLI_linklist_prepend(&ma->bufs, ma->curbuf); - - /* align alloc'ed memory (needed if align > 8) */ - tmp = (unsigned char *)PADUP( (intptr_t) ma->curbuf, ma->align); - ma->cursize -= (int)(tmp - ma->curbuf); - ma->curbuf = tmp; + memarena_curbuf_align(ma); } ptr = ma->curbuf; @@ -125,3 +131,32 @@ void *BLI_memarena_alloc(MemArena *ma, int size) return ptr; } + +/** + * Clear for reuse, avoids re-allocation when an arena may + * otherwise be free'd and recreated. + */ +void BLI_memarena_clear(MemArena *ma) +{ + if (ma->bufs) { + unsigned char *curbuf_prev; + int curbuf_used; + + if (ma->bufs->next) { + BLI_linklist_freeN(ma->bufs->next); + ma->bufs->next = NULL; + } + + curbuf_prev = ma->curbuf; + ma->curbuf = ma->bufs->link; + memarena_curbuf_align(ma); + + /* restore to original size */ + curbuf_used = (int)(curbuf_prev - ma->curbuf); + ma->cursize += curbuf_used; + + if (ma->use_calloc) { + memset(ma->curbuf, 0, (size_t)curbuf_used); + } + } +} |