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