svn merge ^/trunk/blender -r41226:41227 .
[blender.git] / source / blender / blenlib / BLI_mempool.h
index 4ea48929efb7225d5b6a24eeaf6ac9eca01461d3..54b4e5584ebb43d44cb132a5a76092abbf86e04a 100644 (file)
@@ -1,5 +1,4 @@
 /*
- * $Id$
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
 #ifndef BLI_MEMPOOL_H
 #define BLI_MEMPOOL_H
 
-/** \file BLI_storage.h
+/** \file BLI_mempool.h
  *  \ingroup bli
  *  \author Geoffrey Bantle
  *  \brief Simple fast memory allocator.
  */
 
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 struct BLI_mempool;
 
-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);
+#include "BLI_listbase.h"
+#include "BLI_blenlib.h"
+#include <string.h>
+
+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{
+       struct BLI_mempool_chunk *next, *prev;
+       void *data;
+}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*/
+       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, allow_iter;
+}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,
+                                                               int use_sysmalloc, int 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);
+
+/* XXX - copied from BKE_utildefines.h, dont use here because we're in BLI */
+#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__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
+
+/************ inlined stuff ***********/
+#define FREEWORD MAKE_ID('f', 'r', 'e', 'e')
+#include "MEM_guardedalloc.h"
+
+BM_INLINE void *BLI_mempool_alloc(BLI_mempool *pool) {
+       void *retval=NULL;
+       BLI_freenode *curnode=NULL;
+       char *addr=NULL;
+       
+       if (!pool) return NULL;
+       
+       pool->totused++;
+
+       if (!(pool->free)) {
+               int j;
+               /*need to allocate a new chunk*/
+               BLI_mempool_chunk *mpchunk = pool->use_sysmalloc ? (BLI_mempool_chunk*)malloc(sizeof(BLI_mempool_chunk)) :  (BLI_mempool_chunk*)MEM_mallocN(sizeof(BLI_mempool_chunk), "BLI_Mempool Chunk");
+               mpchunk->next = mpchunk->prev = NULL;
+               mpchunk->data = pool->use_sysmalloc ? malloc(pool->csize) : MEM_mallocN(pool->csize, "BLI_Mempool Chunk Data");
+               BLI_addtail(&(pool->chunks), mpchunk);
+
+               pool->free = (BLI_freenode*)mpchunk->data; /*start of the list*/
+               if (pool->allow_iter)
+                       pool->free->freeword = FREEWORD;
+               for(addr = (char*)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*/
+
+               pool->totalloc += pool->pchunk;
+       }
+
+       retval = pool->free;
+       if (pool->allow_iter)
+               pool->free->freeword = 0x7FFFFFFF;
+
+       pool->free = pool->free->next;
+       //memset(retval, 0, pool->esize);
+       return retval;
+}
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif