merge mempool changes from bmesh (adds mempool iterator).

This commit is contained in:
2011-11-16 19:31:42 +00:00
parent 9b17d39ce0
commit 3dcc9aef96
7 changed files with 169 additions and 37 deletions

View 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]){

View 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;
}
/*

View 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)

View File

@@ -34,12 +34,45 @@
* \brief Simple fast memory allocator.
*/
struct BLI_mempool;
#ifdef __cplusplus
extern "C"
{
#endif
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);
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.*/
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

View 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;

View 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 *****
*/
@@ -29,18 +29,36 @@
* \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;

View 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;