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 https://bulletphysics.org
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 #include <string.h>
18 
19 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
20 int gNumAlignedAllocs = 0;
21 int gNumAlignedFree = 0;
22 int gTotalBytesAlignedAllocs = 0; //detect memory leaks
23 #endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS
24 
25 static 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 
32 static void btFreeDefault(void *ptr)
33 {
34  free(ptr);
35 }
36 
39 
40 #if defined(BT_HAS_ALIGNED_ALLOCATOR)
41 #include <malloc.h>
42 static void *btAlignedAllocDefault(size_t size, int alignment)
43 {
44  return _aligned_malloc(size, (size_t)alignment);
45 }
46 
47 static void btAlignedFreeDefault(void *ptr)
48 {
49  _aligned_free(ptr);
50 }
51 #elif defined(__CELLOS_LV2__)
52 #include <stdlib.h>
53 
54 static inline void *btAlignedAllocDefault(size_t size, int alignment)
55 {
56  return memalign(alignment, size);
57 }
58 
59 static inline void btAlignedFreeDefault(void *ptr)
60 {
61  free(ptr);
62 }
63 #else
64 
65 static 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 
84 static 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 
105 void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
106 {
107  sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
108  sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
109 }
110 
111 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
112 
113 static int allocations_id[10241024];
114 static int allocations_bytes[10241024];
115 static int mynumallocs = 0;
116 #include <stdio.h>
117 
118 int 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 
136 struct btDebugPtrMagic
137 {
138  union {
139  void **vptrptr;
140  void *vptr;
141  int *iptr;
142  char *cptr;
143  };
144 };
145 
146 void *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 
203 void 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 
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
static btAlignedAllocFunc * sAlignedAllocFunc
static void btAlignedFreeDefault(void *ptr)
static void * btAllocDefault(size_t size)
static btAllocFunc * sAllocFunc
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be ...
static void * btAlignedAllocDefault(size_t size, int alignment)
static void btFreeDefault(void *ptr)
static btFreeFunc * sFreeFunc
void * btAlignedAllocInternal(size_t size, int alignment)
we probably replace this with our own aligned memory allocator so we replace _aligned_malloc and _ali...
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