merge mempool changes from bmesh (adds mempool iterator).
authorCampbell Barton <ideasman42@gmail.com>
Wed, 16 Nov 2011 19:31:42 +0000 (19:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 16 Nov 2011 19:31:42 +0000 (19:31 +0000)
source/blender/blenkernel/intern/BME_Customdata.c
source/blender/blenkernel/intern/BME_mesh.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenlib/BLI_mempool.h
source/blender/blenlib/intern/BLI_ghash.c
source/blender/blenlib/intern/BLI_mempool.c
source/blender/imbuf/intern/moviecache.c

index 8a6426eb3d5945ae72d96ca57614af44262db717..67215b5e40f8ee6f96f6c29b9e6a0ee80b2edf82 100644 (file)
@@ -86,7 +86,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
        if(data->totlayer){
                /*alloc memory*/
                data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
-               data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 0);
+               data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, FALSE, FALSE);
                /*initialize layer data*/
                for(i=0; i < BME_CD_NUMTYPES; i++){
                        if(init->layout[i]){
index 1b5761fb94ee54aac450e324a0d3064cc34da3be..cda66de6f22bb16cc398cd361a3e4300f91af8b3 100644 (file)
@@ -55,10 +55,10 @@ BME_Mesh *BME_make_mesh(int allocsize[4])
        /*allocate the structure*/
        BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
        /*allocate the memory pools for the mesh elements*/
-       bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], 0);
-       bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], 0);
-       bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], 0);
-       bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], 0);
+       bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], FALSE, FALSE);
+       bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], FALSE, FALSE);
+       bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], FALSE, FALSE);
+       bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], FALSE, FALSE);
        return bm;
 }
 /*     
index d7cc5376e2139c159ac1ffe0039dbd0a58b3ae5a..9cbed451c09ff5e730b637a2b3a2ed2e199e50a5 100644 (file)
@@ -2009,7 +2009,7 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
 
 
 void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
-       if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0);
+       if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, FALSE, FALSE);
 }
 
 void CustomData_bmesh_free_block(CustomData *data, void **block)
index 2a81966986ffac8ee5e443768d03aaa031867dff..f98919fadd3a0f850e4c5535a83116fe9c44f968 100644 (file)
  *  \brief Simple fast memory allocator.
  */
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 struct BLI_mempool;
+struct BLI_mempool_chunk;
+
+typedef struct BLI_mempool BLI_mempool;
+
+/*allow_iter allows iteration on this mempool.  note: this requires that the
+  first four bytes of the elements never contain the character string
+  'free'.  use with care.*/
 
-struct BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk, int use_sysmalloc);
-void *BLI_mempool_alloc(struct BLI_mempool *pool);
-void *BLI_mempool_calloc(struct BLI_mempool *pool);
-void BLI_mempool_free(struct BLI_mempool *pool, void *addr);
-void BLI_mempool_destroy(struct BLI_mempool *pool);
+BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk,
+                                short use_sysmalloc, short allow_iter);
+void *BLI_mempool_alloc(BLI_mempool *pool);
+void *BLI_mempool_calloc(BLI_mempool *pool);
+void BLI_mempool_free(BLI_mempool *pool, void *addr);
+void BLI_mempool_destroy(BLI_mempool *pool);
+int BLI_mempool_count(BLI_mempool *pool);
+
+/** iteration stuff.  note: this may easy to produce bugs with **/
+/*private structure*/
+typedef struct BLI_mempool_iter {
+       BLI_mempool *pool;
+       struct BLI_mempool_chunk *curchunk;
+       int curindex;
+} BLI_mempool_iter;
+
+/*allow iteration on this mempool.  note: this requires that the
+  first four bytes of the elements never contain the character string
+  'free'.  use with care.*/
+void BLI_mempool_allow_iter(BLI_mempool *pool);
+void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter);
+void *BLI_mempool_iterstep(BLI_mempool_iter *iter);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 080dc77fc068c5a832c313e98b0da536a2922b77..c1894088300809a058f00a4612df5d8688d01038 100644 (file)
@@ -60,7 +60,7 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) {
        GHash *gh= MEM_mallocN(sizeof(*gh), info);
        gh->hashfp= hashfp;
        gh->cmpfp= cmpfp;
-       gh->entrypool = BLI_mempool_create(sizeof(Entry), 64, 64, 0);
+       gh->entrypool = BLI_mempool_create(sizeof(Entry), 64, 64, FALSE, FALSE);
 
        gh->cursize= 0;
        gh->nentries= 0;
index 7e79b9f65a1ab17009c7bb91217ece2abbef9d62..4e37ac05214b1b552f235fc5dba3edca48042d77 100644 (file)
@@ -20,7 +20,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Geoffery Bantle
  *
  * ***** END GPL LICENSE BLOCK *****
  */
  *  \ingroup bli
  */
 
-
 /*
-       Simple, fast memory allocator for allocating many elements of the same size.
-*/
+ * Simple, fast memory allocator for allocating many elements of the same size.
+ */
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+
+#include "BLI_mempool.h" /* own include */
+
+#include "DNA_listBase.h"
 
 #include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
-#include "BLI_mempool.h"
-#include <string.h> 
+
+#include <string.h>
+#include <stdlib.h>
+
+/* note: copied from BKE_utildefines.h, dont use here because we're in BLI */
+#ifdef __BIG_ENDIAN__
+/* Big Endian */
+#  define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
+#else
+/* Little Endian */
+#  define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
+#endif
+
+#define FREEWORD MAKE_ID('f', 'r', 'e', 'e')
 
 typedef struct BLI_freenode {
        struct BLI_freenode *next;
+       int freeword; /* used to identify this as a freed node */
 } BLI_freenode;
 
 typedef struct BLI_mempool_chunk {
@@ -50,33 +68,42 @@ typedef struct BLI_mempool_chunk {
 
 typedef struct BLI_mempool {
        struct ListBase chunks;
-       int esize, csize, pchunk;               /*size of elements and chunks in bytes and number of elements per chunk*/
-       struct BLI_freenode     *free;          /*free element list. Interleaved into chunk datas.*/
-       int totalloc, totused; /*total number of elements allocated in total, and currently in use*/
-       int use_sysmalloc;
+       int esize, csize, pchunk;        /* size of elements and chunks in bytes
+                                         * and number of elements per chunk*/
+       short use_sysmalloc, allow_iter;
+       /* keeps aligned to 16 bits */
+
+       BLI_freenode *free;                  /* free element list. Interleaved into chunk datas.*/
+       int totalloc, totused;           /* total number of elements allocated in total,
+                                         * and currently in use*/
 } BLI_mempool;
 
-BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk, int use_sysmalloc)
+#define MEMPOOL_ELEM_SIZE_MIN (sizeof(void *) * 2)
+
+BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk,
+                                short use_sysmalloc, short allow_iter)
 {
        BLI_mempool  *pool = NULL;
        BLI_freenode *lasttail = NULL, *curnode = NULL;
        int i,j, maxchunks;
        char *addr;
-       
-       if (esize < sizeof(void*))
-               esize = sizeof(void*);
-       
+
+       if (esize < MEMPOOL_ELEM_SIZE_MIN)
+               esize = MEMPOOL_ELEM_SIZE_MIN;
+
        /*allocate the pool structure*/
        pool = use_sysmalloc ? malloc(sizeof(BLI_mempool)) : MEM_mallocN(sizeof(BLI_mempool), "memory pool");
-       pool->esize = esize;
+       pool->esize = allow_iter ? MAX2(esize, sizeof(BLI_freenode)) : esize;
        pool->use_sysmalloc = use_sysmalloc;
        pool->pchunk = pchunk;
        pool->csize = esize * pchunk;
        pool->chunks.first = pool->chunks.last = NULL;
        pool->totused= 0;
+       pool->allow_iter= allow_iter;
        
        maxchunks = tote / pchunk + 1;
-       
+       if (maxchunks==0) maxchunks = 1;
+
        /*allocate the actual chunks*/
        for (i=0; i < maxchunks; i++) {
                BLI_mempool_chunk *mpchunk = use_sysmalloc ? malloc(sizeof(BLI_mempool_chunk)) : MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
@@ -84,15 +111,30 @@ BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk, int use_sysmall
                mpchunk->data = use_sysmalloc ? malloc(pool->csize) : MEM_mallocN(pool->csize, "BLI Mempool Chunk Data");
                BLI_addtail(&(pool->chunks), mpchunk);
                
-               if (i==0) pool->free = mpchunk->data; /*start of the list*/
+               if (i==0) {
+                       pool->free = mpchunk->data; /*start of the list*/
+                       if (pool->allow_iter)
+                               pool->free->freeword = FREEWORD;
+               }
+
                /*loop through the allocated data, building the pointer structures*/
                for (addr = mpchunk->data, j=0; j < pool->pchunk; j++) {
                        curnode = ((BLI_freenode*)addr);
                        addr += pool->esize;
                        curnode->next = (BLI_freenode*)addr;
+                       if (pool->allow_iter) {
+                               if (j != pool->pchunk-1)
+                                       curnode->next->freeword = FREEWORD;
+                               curnode->freeword = FREEWORD;
+                       }
                }
                /*final pointer in the previously allocated chunk is wrong.*/
-               if (lasttail) lasttail->next = mpchunk->data;
+               if (lasttail) {
+                       lasttail->next = mpchunk->data;
+                       if (pool->allow_iter)
+                               lasttail->freeword = FREEWORD;
+               }
+
                /*set the end of this chunks memoryy to the new tail for next iteration*/
                lasttail = curnode;
 
@@ -121,10 +163,18 @@ void *BLI_mempool_alloc(BLI_mempool *pool)
                BLI_addtail(&(pool->chunks), mpchunk);
 
                pool->free = mpchunk->data; /*start of the list*/
-               for (addr = mpchunk->data, j=0; j < pool->pchunk; j++) {
+               if (pool->allow_iter)
+                       pool->free->freeword = FREEWORD;
+               for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
                        curnode = ((BLI_freenode*)addr);
                        addr += pool->esize;
                        curnode->next = (BLI_freenode*)addr;
+
+                       if (pool->allow_iter) {
+                               curnode->freeword = FREEWORD;
+                               if (j != pool->pchunk-1)
+                                       curnode->next->freeword = FREEWORD;
+                       }
                }
                curnode->next = NULL; /*terminate the list*/
 
@@ -132,6 +182,9 @@ void *BLI_mempool_alloc(BLI_mempool *pool)
        }
 
        retval = pool->free;
+       if (pool->allow_iter)
+               pool->free->freeword = 0x7FFFFFFF;
+
        pool->free = pool->free->next;
        //memset(retval, 0, pool->esize);
        return retval;
@@ -149,6 +202,8 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
 {
        BLI_freenode *newhead = addr;
 
+       if (pool->allow_iter)
+               newhead->freeword = FREEWORD;
        newhead->next = pool->free;
        pool->free = newhead;
 
@@ -185,6 +240,50 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
        }
 }
 
+void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
+{
+       if (!pool->allow_iter) {
+               fprintf(stderr, "%s: Error! you can't iterate over this mempool!\n", __func__);
+               iter->curchunk = NULL;
+               iter->curindex = 0;
+               
+               return;
+       }
+       
+       iter->pool = pool;
+       iter->curchunk = pool->chunks.first;
+       iter->curindex = 0;
+}
+
+static void *bli_mempool_iternext(BLI_mempool_iter *iter)
+{
+       void *ret = NULL;
+       
+       if (!iter->curchunk || !iter->pool->totused) return NULL;
+       
+       ret = ((char*)iter->curchunk->data) + iter->pool->esize*iter->curindex;
+       
+       iter->curindex++;
+       
+       if (iter->curindex >= iter->pool->pchunk) {
+               iter->curchunk = iter->curchunk->next;
+               iter->curindex = 0;
+       }
+       
+       return ret;
+}
+
+void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
+{
+       BLI_freenode *ret;
+       
+       do {
+               ret = bli_mempool_iternext(iter);
+       } while (ret && ret->freeword == FREEWORD);
+       
+       return ret;
+}
+
 void BLI_mempool_destroy(BLI_mempool *pool)
 {
        BLI_mempool_chunk *mpchunk=NULL;
index 41169a1c211eb936063e339fb5d7c7bd2c89247b..b19b88248f44d143456fe441e225fb79a1367c51 100644 (file)
@@ -204,9 +204,9 @@ struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashC
        MovieCache *cache;
 
        cache= MEM_callocN(sizeof(MovieCache), "MovieCache");
-       cache->keys_pool= BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
-       cache->items_pool= BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
-       cache->userkeys_pool= BLI_mempool_create(keysize, 64, 64, 0);
+       cache->keys_pool= BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, FALSE, FALSE);
+       cache->items_pool= BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, FALSE, FALSE);
+       cache->userkeys_pool= BLI_mempool_create(keysize, 64, 64, FALSE, FALSE);
        cache->hash= BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
 
        cache->keysize= keysize;