270 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			270 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose,
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely,
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btAlignedAllocator.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int gNumAlignedAllocs = 0;
							 | 
						||
| 
								 | 
							
								int gNumAlignedFree = 0;
							 | 
						||
| 
								 | 
							
								int gTotalBytesAlignedAllocs = 0;//detect memory leaks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void *btAllocDefault(size_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return malloc(size);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void btFreeDefault(void *ptr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									free(ptr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static btAllocFunc *sAllocFunc = btAllocDefault;
							 | 
						||
| 
								 | 
							
								static btFreeFunc *sFreeFunc = btFreeDefault;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined (BT_HAS_ALIGNED_ALLOCATOR)
							 | 
						||
| 
								 | 
							
								#include <malloc.h>
							 | 
						||
| 
								 | 
							
								static void *btAlignedAllocDefault(size_t size, int alignment)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return _aligned_malloc(size, (size_t)alignment);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void btAlignedFreeDefault(void *ptr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									_aligned_free(ptr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#elif defined(__CELLOS_LV2__)
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void *btAlignedAllocDefault(size_t size, int alignment)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return memalign(alignment, size);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void btAlignedFreeDefault(void *ptr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									free(ptr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void *btAlignedAllocDefault(size_t size, int alignment)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  void *ret;
							 | 
						||
| 
								 | 
							
								  char *real;
							 | 
						||
| 
								 | 
							
								  real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
							 | 
						||
| 
								 | 
							
								  if (real) {
							 | 
						||
| 
								 | 
							
									ret = btAlignPointer(real + sizeof(void *),alignment);
							 | 
						||
| 
								 | 
							
								    *((void **)(ret)-1) = (void *)(real);
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    ret = (void *)(real);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return (ret);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline void btAlignedFreeDefault(void *ptr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  void* real;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (ptr) {
							 | 
						||
| 
								 | 
							
								    real = *((void **)(ptr)-1);
							 | 
						||
| 
								 | 
							
								    sFreeFunc(real);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
							 | 
						||
| 
								 | 
							
								static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
							 | 
						||
| 
								 | 
							
								  sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
							 | 
						||
| 
								 | 
							
								  sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int allocations_id[10241024];
							 | 
						||
| 
								 | 
							
								static int allocations_bytes[10241024];
							 | 
						||
| 
								 | 
							
								static int mynumallocs = 0;
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int btDumpMemoryLeaks()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int totalLeak = 0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									for (int i=0;i<mynumallocs;i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
							 | 
						||
| 
								 | 
							
										totalLeak+=allocations_bytes[i];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (totalLeak)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return totalLeak;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								//this generic allocator provides the total allocated number of bytes
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct btDebugPtrMagic
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									union
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										void** vptrptr;
							 | 
						||
| 
								 | 
							
										void* vptr;
							 | 
						||
| 
								 | 
							
										int* iptr;
							 | 
						||
| 
								 | 
							
										char* cptr;
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void*   btAlignedAllocInternal  (size_t size, int alignment,int line,char* filename)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (size==0)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										printf("Whaat? size==0");
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									static int allocId = 0;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								 void *ret;
							 | 
						||
| 
								 | 
							
								 char *real;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// to find some particular memory leak, you could do something like this:
							 | 
						||
| 
								 | 
							
								//	if (allocId==172)
							 | 
						||
| 
								 | 
							
								//	{
							 | 
						||
| 
								 | 
							
								//		printf("catch me!\n");
							 | 
						||
| 
								 | 
							
								//	}
							 | 
						||
| 
								 | 
							
								//	if (size>1024*1024)
							 | 
						||
| 
								 | 
							
								//	{
							 | 
						||
| 
								 | 
							
								//		printf("big alloc!%d\n", size);
							 | 
						||
| 
								 | 
							
								//	}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 gTotalBytesAlignedAllocs += size;
							 | 
						||
| 
								 | 
							
								 gNumAlignedAllocs++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								int sz4prt = 4*sizeof(void *);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								 real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
							 | 
						||
| 
								 | 
							
								 if (real) {
							 | 
						||
| 
								 | 
							
									 
							 | 
						||
| 
								 | 
							
								   ret = (void*) btAlignPointer(real + sz4prt, alignment);
							 | 
						||
| 
								 | 
							
									 btDebugPtrMagic p;
							 | 
						||
| 
								 | 
							
									 p.vptr = ret;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 *p.vptrptr = (void*)real;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 *p.iptr = size;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 *p.iptr = allocId;
							 | 
						||
| 
								 | 
							
									 
							 | 
						||
| 
								 | 
							
									 allocations_id[mynumallocs] = allocId;
							 | 
						||
| 
								 | 
							
									 allocations_bytes[mynumallocs] = size;
							 | 
						||
| 
								 | 
							
									 mynumallocs++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 } else {
							 | 
						||
| 
								 | 
							
								   ret = (void *)(real);//??
							 | 
						||
| 
								 | 
							
								 }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs);
							 | 
						||
| 
								 | 
							
									allocId++;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								 int* ptr = (int*)ret;
							 | 
						||
| 
								 | 
							
								 *ptr = 12;
							 | 
						||
| 
								 | 
							
								 return (ret);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void    btAlignedFreeInternal   (void* ptr,int line,char* filename)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 void* real;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 if (ptr) {
							 | 
						||
| 
								 | 
							
									 gNumAlignedFree++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									 btDebugPtrMagic p;
							 | 
						||
| 
								 | 
							
									 p.vptr = ptr;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 real = *p.vptrptr;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 int size = *p.iptr;
							 | 
						||
| 
								 | 
							
									 p.cptr-=sizeof(void*);
							 | 
						||
| 
								 | 
							
									 int allocId = *p.iptr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									 bool found = false;
							 | 
						||
| 
								 | 
							
									 
							 | 
						||
| 
								 | 
							
									 for (int i=0;i<mynumallocs;i++)
							 | 
						||
| 
								 | 
							
									 {
							 | 
						||
| 
								 | 
							
										 if ( allocations_id[i] == allocId)
							 | 
						||
| 
								 | 
							
										 {
							 | 
						||
| 
								 | 
							
											 allocations_id[i] = allocations_id[mynumallocs-1];
							 | 
						||
| 
								 | 
							
											 allocations_bytes[i] = allocations_bytes[mynumallocs-1];
							 | 
						||
| 
								 | 
							
											 mynumallocs--;
							 | 
						||
| 
								 | 
							
											 found = true;
							 | 
						||
| 
								 | 
							
											 break;
							 | 
						||
| 
								 | 
							
										 }
							 | 
						||
| 
								 | 
							
									 }
							 | 
						||
| 
								 | 
							
									 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									gTotalBytesAlignedAllocs -= size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									 int diff = gNumAlignedAllocs-gNumAlignedFree;
							 | 
						||
| 
								 | 
							
									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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   sFreeFunc(real);
							 | 
						||
| 
								 | 
							
								 } else
							 | 
						||
| 
								 | 
							
								 {
							 | 
						||
| 
								 | 
							
									 //printf("deleting a NULL ptr, no effect\n");
							 | 
						||
| 
								 | 
							
								 }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#else //BT_DEBUG_MEMORY_ALLOCATIONS
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void*	btAlignedAllocInternal	(size_t size, int alignment)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									gNumAlignedAllocs++;
							 | 
						||
| 
								 | 
							
									void* ptr;
							 | 
						||
| 
								 | 
							
									ptr = sAlignedAllocFunc(size, alignment);
							 | 
						||
| 
								 | 
							
								//	printf("btAlignedAllocInternal %d, %x\n",size,ptr);
							 | 
						||
| 
								 | 
							
									return ptr;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btAlignedFreeInternal	(void* ptr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (!ptr)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									gNumAlignedFree++;
							 | 
						||
| 
								 | 
							
								//	printf("btAlignedFreeInternal %x\n",ptr);
							 | 
						||
| 
								 | 
							
									sAlignedFreeFunc(ptr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif //BT_DEBUG_MEMORY_ALLOCATIONS
							 | 
						||
| 
								 | 
							
								
							 |