|
Blender
V2.59
|
00001 /* 00002 * $Id: BLI_memarena.c 35246 2011-02-27 20:37:56Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * Efficient memory allocation for lots of similar small chunks. 00029 */ 00030 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_memarena.h" 00040 #include "BLI_linklist.h" 00041 00042 struct MemArena { 00043 unsigned char *curbuf; 00044 int bufsize, cursize; 00045 const char *name; 00046 00047 int use_calloc; 00048 int align; 00049 00050 LinkNode *bufs; 00051 }; 00052 00053 MemArena *BLI_memarena_new(int bufsize, const char *name) { 00054 MemArena *ma= MEM_callocN(sizeof(*ma), "memarena"); 00055 ma->bufsize= bufsize; 00056 ma->align = 8; 00057 ma->name= name; 00058 00059 return ma; 00060 } 00061 00062 void BLI_memarena_use_calloc(MemArena *ma) { 00063 ma->use_calloc= 1; 00064 } 00065 00066 void BLI_memarena_use_malloc(MemArena *ma) { 00067 ma->use_calloc= 0; 00068 } 00069 00070 void BLI_memarena_use_align(struct MemArena *ma, int align) { 00071 /* align should be a power of two */ 00072 ma->align = align; 00073 } 00074 00075 void BLI_memarena_free(MemArena *ma) { 00076 BLI_linklist_free(ma->bufs, (void(*)(void*)) MEM_freeN); 00077 MEM_freeN(ma); 00078 } 00079 00080 /* amt must be power of two */ 00081 #define PADUP(num, amt) ((num+(amt-1))&~(amt-1)) 00082 00083 void *BLI_memarena_alloc(MemArena *ma, int size) { 00084 void *ptr; 00085 00086 /* ensure proper alignment by rounding 00087 * size up to multiple of 8 */ 00088 size= PADUP(size, ma->align); 00089 00090 if (size>ma->cursize) { 00091 unsigned char *tmp; 00092 00093 if(size > ma->bufsize - (ma->align - 1)) 00094 { 00095 ma->cursize = PADUP(size+1, ma->align); 00096 } 00097 else ma->cursize = ma->bufsize; 00098 00099 if(ma->use_calloc) 00100 ma->curbuf= MEM_callocN(ma->cursize, ma->name); 00101 else 00102 ma->curbuf= MEM_mallocN(ma->cursize, ma->name); 00103 00104 BLI_linklist_prepend(&ma->bufs, ma->curbuf); 00105 00106 /* align alloc'ed memory (needed if align > 8) */ 00107 tmp = (unsigned char*)PADUP( (intptr_t) ma->curbuf, ma->align); 00108 ma->cursize -= (tmp - ma->curbuf); 00109 ma->curbuf = tmp; 00110 } 00111 00112 ptr= ma->curbuf; 00113 ma->curbuf+= size; 00114 ma->cursize-= size; 00115 00116 return ptr; 00117 } 00118