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 
36 
37 
38 
39 #if defined (BT_HAS_ALIGNED_ALLOCATOR)
40 #include <malloc.h>
41 static void *btAlignedAllocDefault(size_t size, int alignment)
42 {
43  return _aligned_malloc(size, (size_t)alignment);
44 }
45 
46 static void btAlignedFreeDefault(void *ptr)
47 {
48  _aligned_free(ptr);
49 }
50 #elif defined(__CELLOS_LV2__)
51 #include <stdlib.h>
52 
53 static inline void *btAlignedAllocDefault(size_t size, int alignment)
54 {
55  return memalign(alignment, size);
56 }
57 
58 static inline void btAlignedFreeDefault(void *ptr)
59 {
60  free(ptr);
61 }
62 #else
63 
64 
65 
66 
67 
68 static inline void *btAlignedAllocDefault(size_t size, int alignment)
69 {
70  void *ret;
71  char *real;
72  real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
73  if (real) {
74  ret = btAlignPointer(real + sizeof(void *),alignment);
75  *((void **)(ret)-1) = (void *)(real);
76  } else {
77  ret = (void *)(real);
78  }
79  return (ret);
80 }
81 
82 static inline void btAlignedFreeDefault(void *ptr)
83 {
84  void* real;
85 
86  if (ptr) {
87  real = *((void **)(ptr)-1);
88  sFreeFunc(real);
89  }
90 }
91 #endif
92 
93 
96 
98 {
99  sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
100  sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
101 }
102 
103 void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
104 {
105  sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
106  sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
107 }
108 
109 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
110 
111 static int allocations_id[10241024];
112 static int allocations_bytes[10241024];
113 static int mynumallocs = 0;
114 #include <stdio.h>
115 
116 int btDumpMemoryLeaks()
117 {
118  int totalLeak = 0;
119 
120  for (int i=0;i<mynumallocs;i++)
121  {
122  printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
123  totalLeak+=allocations_bytes[i];
124  }
125  if (totalLeak)
126  {
127  printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
128  }
129  return totalLeak;
130 }
131 //this generic allocator provides the total allocated number of bytes
132 #include <stdio.h>
133 
134 struct btDebugPtrMagic
135 {
136  union
137  {
138  void** vptrptr;
139  void* vptr;
140  int* iptr;
141  char* cptr;
142  };
143 };
144 
145 
146 void* btAlignedAllocInternal (size_t size, int alignment,int line,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 
172 int sz4prt = 4*sizeof(void *);
173 
174  real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
175  if (real) {
176 
177  ret = (void*) btAlignPointer(real + sz4prt, alignment);
178  btDebugPtrMagic p;
179  p.vptr = ret;
180  p.cptr-=sizeof(void*);
181  *p.vptrptr = (void*)real;
182  p.cptr-=sizeof(void*);
183  *p.iptr = size;
184  p.cptr-=sizeof(void*);
185  *p.iptr = allocId;
186 
187  allocations_id[mynumallocs] = allocId;
188  allocations_bytes[mynumallocs] = size;
189  mynumallocs++;
190 
191  } else {
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 
203 void btAlignedFreeInternal (void* ptr,int line,char* filename)
204 {
205 
206  void* real;
207 
208  if (ptr) {
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 
235  gTotalBytesAlignedAllocs -= size;
236 
237  int diff = gNumAlignedAllocs-gNumAlignedFree;
238  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);
239 
240  sFreeFunc(real);
241  } else
242  {
243  //printf("deleting a NULL ptr, no effect\n");
244  }
245 }
246 
247 #else //BT_DEBUG_MEMORY_ALLOCATIONS
248 
249 void* 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 
257 void btAlignedFreeInternal (void* ptr)
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
269 
static void * btAlignedAllocDefault(size_t size, int alignment)
static btFreeFunc * sFreeFunc
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static btAlignedAllocFunc * sAlignedAllocFunc
void( btFreeFunc)(void *memblock)
void *( btAlignedAllocFunc)(size_t size, int alignment)
static btAlignedFreeFunc * sAlignedFreeFunc
void( btAlignedFreeFunc)(void *memblock)
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 ...
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom.
void *( btAllocFunc)(size_t size)
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
static void * btAllocDefault(size_t size)