Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
| Show All 9 Lines | |||||
| 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. | 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. | 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. | 3. This notice may not be removed or altered from any source distribution. | ||||
| */ | */ | ||||
| #include "btAlignedAllocator.h" | #include "btAlignedAllocator.h" | ||||
| #ifdef BT_DEBUG_MEMORY_ALLOCATIONS | |||||
| int gNumAlignedAllocs = 0; | int gNumAlignedAllocs = 0; | ||||
| int gNumAlignedFree = 0; | int gNumAlignedFree = 0; | ||||
| int gTotalBytesAlignedAllocs = 0;//detect memory leaks | int gTotalBytesAlignedAllocs = 0; //detect memory leaks | ||||
| #endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS | |||||
| static void *btAllocDefault(size_t size) | static void *btAllocDefault(size_t size) | ||||
| { | { | ||||
| return malloc(size); | return malloc(size); | ||||
| } | } | ||||
| static void btFreeDefault(void *ptr) | static void btFreeDefault(void *ptr) | ||||
| { | { | ||||
| free(ptr); | free(ptr); | ||||
| } | } | ||||
| static btAllocFunc *sAllocFunc = btAllocDefault; | static btAllocFunc *sAllocFunc = btAllocDefault; | ||||
| static btFreeFunc *sFreeFunc = btFreeDefault; | static btFreeFunc *sFreeFunc = btFreeDefault; | ||||
| #if defined (BT_HAS_ALIGNED_ALLOCATOR) | #if defined(BT_HAS_ALIGNED_ALLOCATOR) | ||||
| #include <malloc.h> | #include <malloc.h> | ||||
| static void *btAlignedAllocDefault(size_t size, int alignment) | static void *btAlignedAllocDefault(size_t size, int alignment) | ||||
| { | { | ||||
| return _aligned_malloc(size, (size_t)alignment); | return _aligned_malloc(size, (size_t)alignment); | ||||
| } | } | ||||
| static void btAlignedFreeDefault(void *ptr) | static void btAlignedFreeDefault(void *ptr) | ||||
| { | { | ||||
| _aligned_free(ptr); | _aligned_free(ptr); | ||||
| } | } | ||||
| #elif defined(__CELLOS_LV2__) | #elif defined(__CELLOS_LV2__) | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| static inline void *btAlignedAllocDefault(size_t size, int alignment) | static inline void *btAlignedAllocDefault(size_t size, int alignment) | ||||
| { | { | ||||
| return memalign(alignment, size); | return memalign(alignment, size); | ||||
| } | } | ||||
| static inline void btAlignedFreeDefault(void *ptr) | static inline void btAlignedFreeDefault(void *ptr) | ||||
| { | { | ||||
| free(ptr); | free(ptr); | ||||
| } | } | ||||
| #else | #else | ||||
| static inline void *btAlignedAllocDefault(size_t size, int alignment) | static inline void *btAlignedAllocDefault(size_t size, int alignment) | ||||
| { | { | ||||
| void *ret; | void *ret; | ||||
| char *real; | char *real; | ||||
| real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1)); | real = (char *)sAllocFunc(size + sizeof(void *) + (alignment - 1)); | ||||
| if (real) { | if (real) | ||||
| { | |||||
| ret = btAlignPointer(real + sizeof(void *),alignment); | ret = btAlignPointer(real + sizeof(void *), alignment); | ||||
| *((void **)(ret)-1) = (void *)(real); | *((void **)(ret)-1) = (void *)(real); | ||||
| } else { | } | ||||
| else | |||||
| { | |||||
| ret = (void *)(real); | ret = (void *)(real); | ||||
| } | } | ||||
| return (ret); | return (ret); | ||||
| } | } | ||||
| static inline void btAlignedFreeDefault(void *ptr) | static inline void btAlignedFreeDefault(void *ptr) | ||||
| { | { | ||||
| void* real; | void *real; | ||||
| if (ptr) { | if (ptr) | ||||
| { | |||||
| real = *((void **)(ptr)-1); | real = *((void **)(ptr)-1); | ||||
| sFreeFunc(real); | sFreeFunc(real); | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; | static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; | ||||
| static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; | static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; | ||||
| void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) | void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) | ||||
| { | { | ||||
| sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; | sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; | ||||
| sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; | sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; | ||||
| } | } | ||||
| void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) | void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) | ||||
| { | { | ||||
| sAllocFunc = allocFunc ? allocFunc : btAllocDefault; | sAllocFunc = allocFunc ? allocFunc : btAllocDefault; | ||||
| sFreeFunc = freeFunc ? freeFunc : btFreeDefault; | sFreeFunc = freeFunc ? freeFunc : btFreeDefault; | ||||
| } | } | ||||
| #ifdef BT_DEBUG_MEMORY_ALLOCATIONS | #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 | //this generic allocator provides the total allocated number of bytes | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) | struct btDebugPtrMagic | ||||
| { | { | ||||
| union { | |||||
| void **vptrptr; | |||||
| void *vptr; | |||||
| int *iptr; | |||||
| char *cptr; | |||||
| }; | |||||
| }; | |||||
| void *btAlignedAllocInternal(size_t size, int alignment, int line, const char *filename) | |||||
| { | |||||
| if (size == 0) | |||||
| { | |||||
| printf("Whaat? size==0"); | |||||
| return 0; | |||||
| } | |||||
| static int allocId = 0; | |||||
| void *ret; | void *ret; | ||||
| char *real; | 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; | gTotalBytesAlignedAllocs += size; | ||||
| gNumAlignedAllocs++; | gNumAlignedAllocs++; | ||||
| int sz4prt = 4 * sizeof(void *); | |||||
| real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1)); | real = (char *)sAllocFunc(size + sz4prt + (alignment - 1)); | ||||
| if (real) { | if (real) | ||||
| ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment); | { | ||||
| *((void **)(ret)-1) = (void *)(real); | ret = (void *)btAlignPointer(real + sz4prt, alignment); | ||||
| *((int*)(ret)-2) = size; | btDebugPtrMagic p; | ||||
| p.vptr = ret; | |||||
| } else { | 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);//?? | ret = (void *)(real); //?? | ||||
| } | } | ||||
| printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size); | 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; | int *ptr = (int *)ret; | ||||
| *ptr = 12; | *ptr = 12; | ||||
| return (ret); | return (ret); | ||||
| } | } | ||||
| void btAlignedFreeInternal (void* ptr,int line,char* filename) | void btAlignedFreeInternal(void *ptr, int line, const char *filename) | ||||
| { | { | ||||
| void* real; | void *real; | ||||
| if (ptr) | |||||
| { | |||||
| gNumAlignedFree++; | gNumAlignedFree++; | ||||
| if (ptr) { | btDebugPtrMagic p; | ||||
| real = *((void **)(ptr)-1); | p.vptr = ptr; | ||||
| int size = *((int*)(ptr)-2); | 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; | gTotalBytesAlignedAllocs -= size; | ||||
| printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,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); | sFreeFunc(real); | ||||
| } else | } | ||||
| else | |||||
| { | { | ||||
| printf("NULL ptr\n"); | //printf("deleting a NULL ptr, no effect\n"); | ||||
| } | } | ||||
| } | } | ||||
| #else //BT_DEBUG_MEMORY_ALLOCATIONS | #else //BT_DEBUG_MEMORY_ALLOCATIONS | ||||
| void* btAlignedAllocInternal (size_t size, int alignment) | void *btAlignedAllocInternal(size_t size, int alignment) | ||||
| { | { | ||||
| gNumAlignedAllocs++; | |||||
| void* ptr; | void *ptr; | ||||
| ptr = sAlignedAllocFunc(size, alignment); | ptr = sAlignedAllocFunc(size, alignment); | ||||
| // printf("btAlignedAllocInternal %d, %x\n",size,ptr); | // printf("btAlignedAllocInternal %d, %x\n",size,ptr); | ||||
| return ptr; | return ptr; | ||||
| } | } | ||||
| void btAlignedFreeInternal (void* ptr) | void btAlignedFreeInternal(void *ptr) | ||||
| { | { | ||||
| if (!ptr) | if (!ptr) | ||||
| { | { | ||||
| return; | return; | ||||
| } | } | ||||
| gNumAlignedFree++; | |||||
| // printf("btAlignedFreeInternal %x\n",ptr); | // printf("btAlignedFreeInternal %x\n",ptr); | ||||
| sAlignedFreeFunc(ptr); | sAlignedFreeFunc(ptr); | ||||
| } | } | ||||
| #endif //BT_DEBUG_MEMORY_ALLOCATIONS | #endif //BT_DEBUG_MEMORY_ALLOCATIONS | ||||