svn merge ^/trunk/blender -r40950:40997, bmesh is in sync with head again
[blender.git] / source / blender / blenlib / BLI_mempool.h
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2008 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): Geoffrey Bantle.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28  
29 #ifndef BLI_MEMPOOL_H
30 #define BLI_MEMPOOL_H
31
32 /** \file BLI_mempool.h
33  *  \ingroup bli
34  *  \author Geoffrey Bantle
35  *  \brief Simple fast memory allocator.
36  */
37
38 #ifdef __cplusplus
39 extern "C"
40 {
41 #endif
42
43 struct BLI_mempool;
44
45 #include "BLI_listbase.h"
46 #include "BLI_blenlib.h"
47 #include <string.h>
48
49 typedef struct BLI_freenode{
50         struct BLI_freenode *next;
51         int freeword; /*used to identify this as a freed node*/
52 }BLI_freenode;
53
54 typedef struct BLI_mempool_chunk{
55         struct BLI_mempool_chunk *next, *prev;
56         void *data;
57 }BLI_mempool_chunk;
58
59 typedef struct BLI_mempool{
60         struct ListBase chunks;
61         int esize, csize, pchunk;               /*size of elements and chunks in bytes and number of elements per chunk*/
62         BLI_freenode *free;             /*free element list. Interleaved into chunk datas.*/
63         int totalloc, totused; /*total number of elements allocated in total, and currently in use*/
64         int use_sysmalloc, allow_iter;
65 }BLI_mempool;
66
67 /*allow_iter allows iteration on this mempool.  note: this requires that the
68   first four bytes of the elements never contain the character string
69   'free'.  use with care.*/
70
71 BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk,
72                                                                 int use_sysmalloc, int allow_iter);
73 //void *BLI_mempool_alloc(BLI_mempool *pool);
74 void *BLI_mempool_calloc(BLI_mempool *pool);
75 void BLI_mempool_free(BLI_mempool *pool, void *addr);
76 void BLI_mempool_destroy(BLI_mempool *pool);
77 int BLI_mempool_count(BLI_mempool *pool);
78
79 /** iteration stuff.  note: this may easy to produce bugs with **/
80 /*private structure*/
81 typedef struct BLI_mempool_iter {
82         BLI_mempool *pool;
83         struct BLI_mempool_chunk *curchunk;
84         int curindex;
85 } BLI_mempool_iter;
86
87 /*allow iteration on this mempool.  note: this requires that the
88   first four bytes of the elements never contain the character string
89   'free'.  use with care.*/
90 void BLI_mempool_allow_iter(BLI_mempool *pool);
91 void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter);
92 void *BLI_mempool_iterstep(BLI_mempool_iter *iter);
93
94 /* XXX - copied from BKE_utildefines.h, dont use here because we're in BLI */
95 #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__hppa__) || defined (__BIG_ENDIAN__)
96         /* Big Endian */
97 #define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
98 #else
99         /* Little Endian */
100 #define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
101 #endif
102
103 /************ inlined stuff ***********/
104 #define FREEWORD MAKE_ID('f', 'r', 'e', 'e')
105 #include "MEM_guardedalloc.h"
106
107 BM_INLINE void *BLI_mempool_alloc(BLI_mempool *pool) {
108         void *retval=NULL;
109         BLI_freenode *curnode=NULL;
110         char *addr=NULL;
111         
112         if (!pool) return NULL;
113         
114         pool->totused++;
115
116         if (!(pool->free)) {
117                 int j;
118                 /*need to allocate a new chunk*/
119                 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");
120                 mpchunk->next = mpchunk->prev = NULL;
121                 mpchunk->data = pool->use_sysmalloc ? malloc(pool->csize) : MEM_mallocN(pool->csize, "BLI_Mempool Chunk Data");
122                 BLI_addtail(&(pool->chunks), mpchunk);
123
124                 pool->free = (BLI_freenode*)mpchunk->data; /*start of the list*/
125                 if (pool->allow_iter)
126                         pool->free->freeword = FREEWORD;
127                 for(addr = (char*)mpchunk->data, j=0; j < pool->pchunk; j++){
128                         curnode = ((BLI_freenode*)addr);
129                         addr += pool->esize;
130                         curnode->next = (BLI_freenode*)addr;
131
132                         if (pool->allow_iter) {
133                                 curnode->freeword = FREEWORD;
134                                 if (j != pool->pchunk-1)
135                                         curnode->next->freeword = FREEWORD;
136                         }
137                 }
138                 curnode->next = NULL; /*terminate the list*/
139
140                 pool->totalloc += pool->pchunk;
141         }
142
143         retval = pool->free;
144         if (pool->allow_iter)
145                 pool->free->freeword = 0x7FFFFFFF;
146
147         pool->free = pool->free->next;
148         //memset(retval, 0, pool->esize);
149         return retval;
150 }
151
152 #ifdef __cplusplus
153 }
154 #endif
155
156 #endif