Bullet Collision Detection & Physics Library: btAlignedAllocator.cpp Source File

Bullet Collision Detection & Physics Library

btAlignedAllocator.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "btAlignedAllocator.h"
17
18 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
19 int gNumAlignedAllocs = 0;
20 int gNumAlignedFree = 0;
21 int gTotalBytesAlignedAllocs = 0; //detect memory leaks
22 #endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS
23
24 static void *btAllocDefault(size_t size)
25 {
26 return malloc(size);
27 }
28
29 static void btFreeDefault(void *ptr)
30 {
31 free(ptr);
32 }
33
34 static btAllocFunc *sAllocFunc = btAllocDefault;
35 static btFreeFunc *sFreeFunc = btFreeDefault;
36
37 #if defined(BT_HAS_ALIGNED_ALLOCATOR)
38 #include <malloc.h>
39 static void *btAlignedAllocDefault(size_t size, int alignment)
40 {
41 return _aligned_malloc(size, (size_t)alignment);
42 }
43
44 static void btAlignedFreeDefault(void *ptr)
45 {
46 _aligned_free(ptr);
47 }
48 #elif defined(__CELLOS_LV2__)
49 #include <stdlib.h>
50
51 static inline void *btAlignedAllocDefault(size_t size, int alignment)
52 {
53 return memalign(alignment, size);
54 }
55
56 static inline void btAlignedFreeDefault(void *ptr)
57 {
58 free(ptr);
59 }
60 #else
61
62 static inline void *btAlignedAllocDefault(size_t size, int alignment)
63 {
64 void *ret;
65 char *real;
66 real = (char *)sAllocFunc(size + sizeof(void *) + (alignment - 1));
67 if (real)
68 {
69 ret = btAlignPointer(real + sizeof(void *), alignment);
70 *((void **)(ret)-1) = (void *)(real);
71 }
72 else
73 {
74 ret = (void *)(real);
75 }
76 return (ret);
77 }
78
79 static inline void btAlignedFreeDefault(void *ptr)
80 {
81 void *real;
82
83 if (ptr)
84 {
85 real = *((void **)(ptr)-1);
86 sFreeFunc(real);
87 }
88 }
89 #endif
90
91 static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
92 static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
93
94 void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
95 {
96 sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
97 sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
98 }
99
100 void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
101 {
102 sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
103 sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
104 }
105
106 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
107
108 static int allocations_id[10241024];
109 static int allocations_bytes[10241024];
110 static int mynumallocs = 0;
111 #include <stdio.h>
112
113 int btDumpMemoryLeaks()
114 {
115 int totalLeak = 0;
116
117 for (int i = 0; i < mynumallocs; i++)
118 {
119 printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
120 totalLeak += allocations_bytes[i];
121 }
122 if (totalLeak)
123 {
124 printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n", mynumallocs, totalLeak);
125 }
126 return totalLeak;
127 }
128 //this generic allocator provides the total allocated number of bytes
129 #include <stdio.h>
130
131 struct btDebugPtrMagic
132 {
133 union {
134 void **vptrptr;
135 void *vptr;
136 int *iptr;
137 char *cptr;
138 };
139 };
140
141 void *btAlignedAllocInternal(size_t size, int alignment, int line, char *filename)
142 {
143 if (size == 0)
144 {
145 printf("Whaat? size==0");
146 return 0;
147 }
148 static int allocId = 0;
149
150 void *ret;
151 char *real;
152
153 // to find some particular memory leak, you could do something like this:
154 // if (allocId==172)
155 // {
156 // printf("catch me!\n");
157 // }
158 // if (size>1024*1024)
159 // {
160 // printf("big alloc!%d\n", size);
161 // }
162
163 gTotalBytesAlignedAllocs += size;
164 gNumAlignedAllocs++;
165
166 int sz4prt = 4 * sizeof(void *);
167
168 real = (char *)sAllocFunc(size + sz4prt + (alignment - 1));
169 if (real)
170 {
171 ret = (void *)btAlignPointer(real + sz4prt, alignment);
172 btDebugPtrMagic p;
173 p.vptr = ret;
174 p.cptr -= sizeof(void *);
175 *p.vptrptr = (void *)real;
176 p.cptr -= sizeof(void *);
177 *p.iptr = size;
178 p.cptr -= sizeof(void *);
179 *p.iptr = allocId;
180
181 allocations_id[mynumallocs] = allocId;
182 allocations_bytes[mynumallocs] = size;
183 mynumallocs++;
184 }
185 else
186 {
187 ret = (void *)(real); //??
188 }
189
190 printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n", allocId, real, filename, line, size, gTotalBytesAlignedAllocs);
191 allocId++;
192
193 int *ptr = (int *)ret;
194 *ptr = 12;
195 return (ret);
196 }
197
198 void btAlignedFreeInternal(void *ptr, int line, char *filename)
199 {
200 void *real;
201
202 if (ptr)
203 {
204 gNumAlignedFree++;
205
206 btDebugPtrMagic p;
207 p.vptr = ptr;
208 p.cptr -= sizeof(void *);
209 real = *p.vptrptr;
210 p.cptr -= sizeof(void *);
211 int size = *p.iptr;
212 p.cptr -= sizeof(void *);
213 int allocId = *p.iptr;
214
215 bool found = false;
216
217 for (int i = 0; i < mynumallocs; i++)
218 {
219 if (allocations_id[i] == allocId)
220 {
221 allocations_id[i] = allocations_id[mynumallocs - 1];
222 allocations_bytes[i] = allocations_bytes[mynumallocs - 1];
223 mynumallocs--;
224 found = true;
225 break;
226 }
227 }
228
229 gTotalBytesAlignedAllocs -= size;
230
231 int diff = gNumAlignedAllocs - gNumAlignedFree;
232 printf("free %d at address %x, from %s,line %d, size %d (total remain = %d in %d non-freed allocations)\n", allocId, real, filename, line, size, gTotalBytesAlignedAllocs, diff);
233
234 sFreeFunc(real);
235 }
236 else
237 {
238 //printf("deleting a NULL ptr, no effect\n");
239 }
240 }
241
242 #else //BT_DEBUG_MEMORY_ALLOCATIONS
243
244 void *btAlignedAllocInternal(size_t size, int alignment)
245 {
246 void *ptr;
247 ptr = sAlignedAllocFunc(size, alignment);
248 // printf("btAlignedAllocInternal %d, %x\n",size,ptr);
249 return ptr;
250 }
251
252 void btAlignedFreeInternal(void *ptr)
253 {
254 if (!ptr)
255 {
256 return;
257 }
258
259 // printf("btAlignedFreeInternal %x\n",ptr);
260 sAlignedFreeFunc(ptr);
261 }
262
263 #endif //BT_DEBUG_MEMORY_ALLOCATIONS
btAlignedAllocFunc
void *() btAlignedAllocFunc(size_t size, int alignment)
Definition: btAlignedAllocator.h:52
btAlignedAllocDefault
static void * btAlignedAllocDefault(size_t size, int alignment)
Definition: btAlignedAllocator.cpp:62
sFreeFunc
static btFreeFunc * sFreeFunc
Definition: btAlignedAllocator.cpp:35
size
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
btAlignedAllocator.h
sAlignedAllocFunc
static btAlignedAllocFunc * sAlignedAllocFunc
Definition: btAlignedAllocator.cpp:91
btAlignedFreeFunc
void() btAlignedFreeFunc(void *memblock)
Definition: btAlignedAllocator.h:53
sAlignedFreeFunc
static btAlignedFreeFunc * sAlignedFreeFunc
Definition: btAlignedAllocator.cpp:92
btAlignedFreeDefault
static void btAlignedFreeDefault(void *ptr)
Definition: btAlignedAllocator.cpp:79
btFreeDefault
static void btFreeDefault(void *ptr)
Definition: btAlignedAllocator.cpp:29
btAlignedAllocSetCustomAligned
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be ...
Definition: btAlignedAllocator.cpp:94
btAlignedAllocSetCustom
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom.
Definition: btAlignedAllocator.cpp:100
btFreeFunc
void() btFreeFunc(void *memblock)
Definition: btAlignedAllocator.h:55
btAlignedFreeInternal
void btAlignedFreeInternal(void *ptr)
Definition: btAlignedAllocator.cpp:252
btAlignedAllocInternal
void * btAlignedAllocInternal(size_t size, int alignment)
we probably replace this with our own aligned memory allocator so we replace _aligned_malloc and _ali...
Definition: btAlignedAllocator.cpp:244
btAlignPointer
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:794
sAllocFunc
static btAllocFunc * sAllocFunc
Definition: btAlignedAllocator.cpp:34
btAllocFunc
void *() btAllocFunc(size_t size)
Definition: btAlignedAllocator.h:54
btAllocDefault
static void * btAllocDefault(size_t size)
Definition: btAlignedAllocator.cpp:24