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 
20 int gTotalBytesAlignedAllocs = 0;//detect memory leaks
21 
22 static void *btAllocDefault(size_t size)
23 {
24  return malloc(size);
25 }
26 
27 static void btFreeDefault(void *ptr)
28 {
29  free(ptr);
30 }
31 
34 
35 
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 
63 
64 
65 
66 static inline void *btAlignedAllocDefault(size_t size, int alignment)
67 {
68  void *ret;
69  char *real;
70  real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
71  if (real) {
72  ret = btAlignPointer(real + sizeof(void *),alignment);
73  *((void **)(ret)-1) = (void *)(real);
74  } else {
75  ret = (void *)(real);
76  }
77  return (ret);
78 }
79 
80 static inline void btAlignedFreeDefault(void *ptr)
81 {
82  void* real;
83 
84  if (ptr) {
85  real = *((void **)(ptr)-1);
86  sFreeFunc(real);
87  }
88 }
89 #endif
90 
91 
94 
96 {
97  sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
98  sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
99 }
100 
101 void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
102 {
103  sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
104  sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
105 }
106 
107 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
108 
109 static int allocations_id[10241024];
110 static int allocations_bytes[10241024];
111 static int mynumallocs = 0;
112 #include <stdio.h>
113 
114 int btDumpMemoryLeaks()
115 {
116  int totalLeak = 0;
117 
118  for (int i=0;i<mynumallocs;i++)
119  {
120  printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
121  totalLeak+=allocations_bytes[i];
122  }
123  if (totalLeak)
124  {
125  printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
126  }
127  return totalLeak;
128 }
129 //this generic allocator provides the total allocated number of bytes
130 #include <stdio.h>
131 
132 struct btDebugPtrMagic
133 {
134  union
135  {
136  void** vptrptr;
137  void* vptr;
138  int* iptr;
139  char* cptr;
140  };
141 };
142 
143 
144 void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename)
145 {
146  if (size==0)
147  {
148  printf("Whaat? size==0");
149  return 0;
150  }
151  static int allocId = 0;
152 
153  void *ret;
154  char *real;
155 
156 // to find some particular memory leak, you could do something like this:
157 // if (allocId==172)
158 // {
159 // printf("catch me!\n");
160 // }
161 // if (size>1024*1024)
162 // {
163 // printf("big alloc!%d\n", size);
164 // }
165 
168 
169 
170 int sz4prt = 4*sizeof(void *);
171 
172  real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
173  if (real) {
174 
175  ret = (void*) btAlignPointer(real + sz4prt, alignment);
176  btDebugPtrMagic p;
177  p.vptr = ret;
178  p.cptr-=sizeof(void*);
179  *p.vptrptr = (void*)real;
180  p.cptr-=sizeof(void*);
181  *p.iptr = size;
182  p.cptr-=sizeof(void*);
183  *p.iptr = allocId;
184 
185  allocations_id[mynumallocs] = allocId;
186  allocations_bytes[mynumallocs] = size;
187  mynumallocs++;
188 
189  } else {
190  ret = (void *)(real);//??
191  }
192 
193  printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs);
194  allocId++;
195 
196  int* ptr = (int*)ret;
197  *ptr = 12;
198  return (ret);
199 }
200 
201 void btAlignedFreeInternal (void* ptr,int line,char* filename)
202 {
203 
204  void* real;
205 
206  if (ptr) {
207  gNumAlignedFree++;
208 
209  btDebugPtrMagic p;
210  p.vptr = ptr;
211  p.cptr-=sizeof(void*);
212  real = *p.vptrptr;
213  p.cptr-=sizeof(void*);
214  int size = *p.iptr;
215  p.cptr-=sizeof(void*);
216  int allocId = *p.iptr;
217 
218  bool found = false;
219 
220  for (int i=0;i<mynumallocs;i++)
221  {
222  if ( allocations_id[i] == allocId)
223  {
224  allocations_id[i] = allocations_id[mynumallocs-1];
225  allocations_bytes[i] = allocations_bytes[mynumallocs-1];
226  mynumallocs--;
227  found = true;
228  break;
229  }
230  }
231 
232 
234 
236  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);
237 
238  sFreeFunc(real);
239  } else
240  {
241  //printf("deleting a NULL ptr, no effect\n");
242  }
243 }
244 
245 #else //BT_DEBUG_MEMORY_ALLOCATIONS
246 
247 void* btAlignedAllocInternal (size_t size, int alignment)
248 {
250  void* ptr;
251  ptr = sAlignedAllocFunc(size, alignment);
252 // printf("btAlignedAllocInternal %d, %x\n",size,ptr);
253  return ptr;
254 }
255 
256 void btAlignedFreeInternal (void* ptr)
257 {
258  if (!ptr)
259  {
260  return;
261  }
262 
263  gNumAlignedFree++;
264 // printf("btAlignedFreeInternal %x\n",ptr);
265  sAlignedFreeFunc(ptr);
266 }
267 
268 #endif //BT_DEBUG_MEMORY_ALLOCATIONS
269 
void *() btAlignedAllocFunc(size_t size, int alignment)
static void * btAlignedAllocDefault(size_t size, int alignment)
static btFreeFunc * sFreeFunc
int gNumAlignedFree
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static btAlignedAllocFunc * sAlignedAllocFunc
int gTotalBytesAlignedAllocs
void() btAlignedFreeFunc(void *memblock)
static btAlignedFreeFunc * sAlignedFreeFunc
static void btAlignedFreeDefault(void *ptr)
static void btFreeDefault(void *ptr)
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be ...
int gNumAlignedAllocs
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 btAlignedFreeInternal(void *ptr)
void * btAlignedAllocInternal(size_t size, int alignment)
we probably replace this with our own aligned memory allocator so we replace _aligned_malloc and _ali...
T * btAlignPointer(T *unalignedPtr, size_t alignment)
align a pointer to the provided alignment, upwards
Definition: btScalar.h:792
static btAllocFunc * sAllocFunc
void *() btAllocFunc(size_t size)
static void * btAllocDefault(size_t size)