1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Sources
4 // Last modified: 08/17/2008
5 //
6 // Filename: src-IL/src/il_alloc.c
7 //
8 // Description: Memory allocation functions
9 //
10 //-----------------------------------------------------------------------------
11
12
13 #define __ALLOC_C
14
15 // Memory leak detection
16 #ifdef _WIN32
17 #ifdef _DEBUG
18 #define _CRTDBG_MAP_ALLOC
19 #include <stdlib.h>
20 #ifndef _WIN32_WCE // Does not have this header.
21 #include <crtdbg.h>
22 #endif
23 #endif
24 #endif//_WIN32
25
26 #include "il_internal.h"
27 #include <stdlib.h>
28 #include <math.h>
29
30 #ifdef MM_MALLOC
31 #include <mm_malloc.h>
32 #endif
33
34 static void ILAPIENTRY DefaultFreeFunc(const void * CONST_RESTRICT Ptr);
35 static void* ILAPIENTRY DefaultAllocFunc(const ILsizei Size);
36
37 static mAlloc ialloc_ptr = DefaultAllocFunc;
38 static mFree ifree_ptr = DefaultFreeFunc;
39
40 /*** Vector Allocation/Deallocation Function ***/
41 #ifdef VECTORMEM
vec_malloc(const ILsizei size)42 void *vec_malloc(const ILsizei size)
43 {
44 const ILsizei _size = size % 16 > 0 ? size + 16 - (size % 16) : size; // align size value
45
46 #ifdef MM_MALLOC
47 return _mm_malloc(_size,16);
48 #else
49 #ifdef VALLOC
50 return valloc( _size );
51 #else
52 #ifdef POSIX_MEMALIGN
53 char *buffer;
54 return posix_memalign((void**)&buffer, 16, _size) == 0 ? buffer : NULL;
55 #else
56 #ifdef MEMALIGN
57 return memalign( 16, _size );
58 #else
59 // Memalign hack from ffmpeg for MinGW
60 void *ptr;
61 int diff;
62 ptr = malloc(_size+16+1);
63 diff= ((-(int)ptr - 1)&15) + 1;
64 ptr = (void*)(((char*)ptr)+diff);
65 ((char*)ptr)[-1]= diff;
66 return ptr;
67 #endif //MEMALIGN
68 #endif //POSIX_MEMALIGN
69 #endif //VALLOC
70 #endif //MM_MALLOC
71 }
72
ivec_align_buffer(void * buffer,const ILsizei size)73 void *ivec_align_buffer(void *buffer, const ILsizei size)
74 {
75 if( (ILsizei)buffer % 16 != 0 ) {
76 void *aligned_buffer = vec_malloc( size );
77 memcpy( aligned_buffer, buffer, size );
78 ifree( buffer );
79 return aligned_buffer;
80 }
81 return buffer;
82 }
83 #endif
84
85
86 /*** Allocation/Deallocation Function ***/
ialloc(const ILsizei Size)87 void* ILAPIENTRY ialloc(const ILsizei Size)
88 {
89 void *Ptr = ialloc_ptr(Size);
90 if (Ptr == NULL)
91 ilSetError(IL_OUT_OF_MEMORY);
92 return Ptr;
93 }
94
ifree(const void * CONST_RESTRICT Ptr)95 void ILAPIENTRY ifree(const void * CONST_RESTRICT Ptr)
96 {
97 if (Ptr == NULL)
98 return;
99 ifree_ptr(Ptr);
100 return;
101 }
102
icalloc(const ILsizei Size,const ILsizei Num)103 void* ILAPIENTRY icalloc(const ILsizei Size, const ILsizei Num)
104 {
105 void *Ptr = ialloc(Size * Num);
106 if (Ptr == NULL)
107 return Ptr;
108 imemclear(Ptr, Size * Num);
109 return Ptr;
110 }
111
112 /*** Default Allocation/Deallocation Function ***/
DefaultAllocFunc(const ILsizei Size)113 static void* ILAPIENTRY DefaultAllocFunc(const ILsizei Size)
114 {
115 #ifdef VECTORMEM
116 return (void*)vec_malloc(Size);
117 #else
118 return malloc(Size);
119 #endif //VECTORMEM
120 }
121
DefaultFreeFunc(const void * CONST_RESTRICT ptr)122 static void ILAPIENTRY DefaultFreeFunc(const void * CONST_RESTRICT ptr)
123 {
124 if (ptr)
125 {
126 #if defined(VECTORMEM) && defined(MM_MALLOC)
127 _mm_free((void*)ptr);
128 #else
129 #if defined(VECTORMEM) & !defined(POSIX_MEMALIGN) & !defined(VALLOC) & !defined(MEMALIGN) & !defined(MM_MALLOC)
130 free(((char*)Ptr) - ((char*)Ptr)[-1]);
131 #else
132 free((void*)ptr);
133 #endif //OTHERS...
134 #endif //MM_MALLOC
135 }
136 }
137
138 /*** Manipulate Allocation/Deallocation Function ***/
ilResetMemory()139 void ILAPIENTRY ilResetMemory() // Deprecated
140 {
141 ialloc_ptr = DefaultAllocFunc;
142 ifree_ptr = DefaultFreeFunc;
143 }
144
ilSetMemory(mAlloc AllocFunc,mFree FreeFunc)145 void ILAPIENTRY ilSetMemory(mAlloc AllocFunc, mFree FreeFunc)
146 {
147 ialloc_ptr = AllocFunc == NULL ? DefaultAllocFunc : AllocFunc;
148 ifree_ptr = FreeFunc == NULL ? DefaultFreeFunc : FreeFunc;
149 }
150
151
152 /*#if defined(_WIN32) && defined(_MEM_DEBUG)
153 #include <windows.h>
154
155 int bAtexit = 0;
156
157
158 typedef struct ALLOC_INFO
159 {
160 unsigned long address;
161 unsigned long size;
162 char file[64];
163 unsigned long line;
164 struct ALLOC_INFO *Next;
165 } ALLOC_INFO;
166 ALLOC_INFO *AllocList;
167
168
169 void AddTrack(unsigned long addr, unsigned long size, const char *file, unsigned long line)
170 {
171 ALLOC_INFO *Temp;
172
173 if (AllocList == NULL) {
174 AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
175 AllocList->address = addr;
176 AllocList->size = size;
177 AllocList->line = line;
178 strncpy(AllocList->file, file, 63);
179 AllocList->Next = NULL;
180 }
181 else {
182 Temp = AllocList;
183 AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
184 AllocList->address = addr;
185 AllocList->size = size;
186 AllocList->line = line;
187 strncpy(AllocList->file, file, 63);
188 AllocList->Next = Temp;
189 }
190
191 return;
192 }
193
194
195 void RemoveTrack(unsigned long addr)
196 {
197 ALLOC_INFO *Temp, *Prev;
198
199 Temp = AllocList;
200 Prev = NULL;
201
202 if (Temp == NULL)
203 return;
204
205 while (Temp != NULL) {
206 if (Temp->address == addr) {
207 if (Prev == NULL) {
208 AllocList = Temp->Next;
209 free(Temp);
210 }
211 else {
212 Prev->Next = Temp->Next;
213 free(Temp);
214 }
215 break;
216 }
217 Prev = Temp;
218 Temp = Temp->Next;
219 }
220
221 return;
222 }
223
224
225 void DumpUnfreed(void)
226 {
227 unsigned long TotalSize = 0;
228 char buf[1024];
229 ALLOC_INFO *i = AllocList;
230
231 OutputDebugString("DevIL Unfreed Information:\n");
232 while (i != NULL) {
233 sprintf(buf, "%s(%d) : %d bytes unfreed at %d\n", i->file, i->line, i->size, i->address);
234 OutputDebugString(buf);
235 TotalSize += i->size;
236
237 AllocList = i->Next;
238 free(i);
239 i = AllocList;
240 }
241
242 sprintf(buf, "-----------------------------------------------------------\n");
243 OutputDebugString(buf);
244 sprintf(buf, "Total Unfreed: %d bytes\n\n\n", TotalSize);
245 OutputDebugString(buf);
246 }
247
248 void AddToAtexit()
249 {
250 if (bAtexit)
251 return;
252 atexit(DumpUnfreed);
253 bAtexit = 1;
254 }
255
256 void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line)
257 {
258 void *ptr;
259 ptr = calloc(size, num);
260 if (!ptr)
261 return NULL;
262 AddToAtexit();
263 AddTrack((unsigned long)ptr, size * num, file, line);
264 return ptr;
265 }
266
267
268 void *m_alloc(unsigned long size, const char *file, unsigned long line)
269 {
270 void *ptr;
271 ptr = malloc(size);
272 if (!ptr)
273 return NULL;
274 AddToAtexit();
275 AddTrack((unsigned long)ptr, size, file, line);
276 return ptr;
277 }
278
279
280 void f_ree(void *ptr)
281 {
282 RemoveTrack((unsigned long)ptr);
283 free(ptr);
284 return;
285 }
286
287 #endif//defined(_WIN32) && defined(_MEM_DEBUG)*/
288