OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 | 11 |
12 /* | 12 /* |
13 vpx_mem_tracker.c | 13 vpx_mem_tracker.c |
14 | 14 |
15 jwz 2003-09-30: | 15 jwz 2003-09-30: |
16 Stores a list of addreses, their size, and file and line they came from. | 16 Stores a list of addreses, their size, and file and line they came from. |
17 All exposed lib functions are prefaced by vpx_ and allow the global list | 17 All exposed lib functions are prefaced by vpx_ and allow the global list |
18 to be thread safe. | 18 to be thread safe. |
19 Current supported platforms are: | 19 Current supported platforms are: |
20 Linux, Win32, win_ce and vx_works | 20 Linux, Win32, win_ce and vx_works |
21 Further support can be added by defining the platform specific mutex | 21 Further support can be added by defining the platform specific mutex |
22 in the memory_tracker struct as well as calls to create/destroy/lock/unlock | 22 in the memory_tracker struct as well as calls to create/destroy/lock/unlock |
23 the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/un
lock_mutex | 23 the mutex in vpx_memory_tracker_init/Destroy and memory_tracker_lock_mutex/un
lock_mutex |
24 */ | 24 */ |
25 #include "vpx_config.h" | 25 #include "vpx_ports/config.h" |
26 | 26 |
27 #if defined(__uClinux__) | 27 #if defined(__uClinux__) |
28 # include <lddk.h> | 28 # include <lddk.h> |
29 #endif | 29 #endif |
30 | 30 |
31 #if HAVE_PTHREAD_H | 31 #if HAVE_PTHREAD_H |
32 # include <pthread.h> | 32 # include <pthread.h> |
33 #elif defined(WIN32) || defined(_WIN32_WCE) | 33 #elif defined(WIN32) || defined(_WIN32_WCE) |
34 # define WIN32_LEAN_AND_MEAN | 34 # define WIN32_LEAN_AND_MEAN |
35 # include <windows.h> | 35 # include <windows.h> |
36 # include <winbase.h> | 36 # include <winbase.h> |
37 #elif defined(VXWORKS) | 37 #elif defined(VXWORKS) |
38 # include <sem_lib.h> | 38 # include <sem_lib.h> |
39 #endif | 39 #endif |
40 | 40 |
41 #include <stdio.h> | 41 #include <stdio.h> |
42 #include <stdlib.h> | 42 #include <stdlib.h> |
43 #include <string.h> //VXWORKS doesn't have a malloc/memory.h file, | 43 #include <string.h> // VXWORKS doesn't have a malloc/memory.h file, |
44 //this should pull in malloc,free,etc. | 44 // this should pull in malloc,free,etc. |
45 #include <stdarg.h> | 45 #include <stdarg.h> |
46 | 46 |
47 #include "include/vpx_mem_tracker.h" | 47 #include "include/vpx_mem_tracker.h" |
48 | 48 |
49 #undef vpx_malloc //undefine any vpx_mem macros that may affect calls to | 49 #undef vpx_malloc // undefine any vpx_mem macros that may affect calls to |
50 #undef vpx_free //memory functions in this file | 50 #undef vpx_free // memory functions in this file |
51 #undef vpx_memcpy | 51 #undef vpx_memcpy |
52 #undef vpx_memset | 52 #undef vpx_memset |
53 | 53 |
54 | 54 |
55 #ifndef USE_GLOBAL_FUNCTION_POINTERS | 55 #ifndef USE_GLOBAL_FUNCTION_POINTERS |
56 # define USE_GLOBAL_FUNCTION_POINTERS 0 //use function pointers instead of co
mpiled functions. | 56 # define USE_GLOBAL_FUNCTION_POINTERS 0 // use function pointers instead of c
ompiled functions. |
57 #endif | 57 #endif |
58 | 58 |
59 #if USE_GLOBAL_FUNCTION_POINTERS | 59 #if USE_GLOBAL_FUNCTION_POINTERS |
60 static mem_track_malloc_func g_malloc = malloc; | 60 static mem_track_malloc_func g_malloc = malloc; |
61 static mem_track_calloc_func g_calloc = calloc; | 61 static mem_track_calloc_func g_calloc = calloc; |
62 static mem_track_realloc_func g_realloc = realloc; | 62 static mem_track_realloc_func g_realloc = realloc; |
63 static mem_track_free_func g_free = free; | 63 static mem_track_free_func g_free = free; |
64 static mem_track_memcpy_func g_memcpy = memcpy; | 64 static mem_track_memcpy_func g_memcpy = memcpy; |
65 static mem_track_memset_func g_memset = memset; | 65 static mem_track_memset_func g_memset = memset; |
66 static mem_track_memmove_func g_memmove = memmove; | 66 static mem_track_memmove_func g_memmove = memmove; |
(...skipping 20 matching lines...) Expand all Loading... |
87 | 87 |
88 #if defined(NO_MUTEX) | 88 #if defined(NO_MUTEX) |
89 # define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited) | 89 # define memory_tracker_lock_mutex() (!g_b_mem_tracker_inited) |
90 # define memory_tracker_unlock_mutex() | 90 # define memory_tracker_unlock_mutex() |
91 #else | 91 #else |
92 static int memory_tracker_lock_mutex(); | 92 static int memory_tracker_lock_mutex(); |
93 static int memory_tracker_unlock_mutex(); | 93 static int memory_tracker_unlock_mutex(); |
94 #endif | 94 #endif |
95 | 95 |
96 #ifndef VPX_NO_GLOBALS | 96 #ifndef VPX_NO_GLOBALS |
97 struct memory_tracker | 97 struct memory_tracker { |
98 { | 98 struct mem_block *head, |
99 struct mem_block *head, | 99 * tail; |
100 * tail; | 100 int len, |
101 int len, | 101 totalsize; |
102 totalsize; | 102 unsigned int current_allocated, |
103 unsigned int current_allocated, | 103 max_allocated; |
104 max_allocated; | |
105 | 104 |
106 #if HAVE_PTHREAD_H | 105 #if HAVE_PTHREAD_H |
107 pthread_mutex_t mutex; | 106 pthread_mutex_t mutex; |
108 #elif defined(WIN32) || defined(_WIN32_WCE) | 107 #elif defined(WIN32) || defined(_WIN32_WCE) |
109 HANDLE mutex; | 108 HANDLE mutex; |
110 #elif defined(VXWORKS) | 109 #elif defined(VXWORKS) |
111 SEM_ID mutex; | 110 SEM_ID mutex; |
112 #elif defined(NO_MUTEX) | 111 #elif defined(NO_MUTEX) |
113 #else | 112 #else |
114 #error "No mutex type defined for this platform!" | 113 #error "No mutex type defined for this platform!" |
115 #endif | 114 #endif |
116 | 115 |
117 int padding_size, | 116 int padding_size, |
118 pad_value; | 117 pad_value; |
119 }; | 118 }; |
120 | 119 |
121 static struct memory_tracker memtrack; //our global memory allocation list | 120 static struct memory_tracker memtrack; // our global memory allocation list |
122 static int g_b_mem_tracker_inited = 0; //indicates whether the global list h
as | 121 static int g_b_mem_tracker_inited = 0; // indicates whether the global list
has |
123 //been initialized (1:yes/0:no) | 122 // been initialized (1:yes/0:no) |
124 static struct | 123 static struct { |
125 { | 124 FILE *file; |
126 FILE *file; | 125 int type; |
127 int type; | 126 void (*func)(void *userdata, const char *fmt, va_list args); |
128 void (*func)(void *userdata, const char *fmt, va_list args); | 127 void *userdata; |
129 void *userdata; | |
130 } g_logging = {NULL, 0, NULL, NULL}; | 128 } g_logging = {NULL, 0, NULL, NULL}; |
131 #else | 129 #else |
132 # include "vpx_global_handling.h" | 130 # include "vpx_global_handling.h" |
133 #define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited) | 131 #define g_b_mem_tracker_inited vpxglobalm(vpxmem,g_b_mem_tracker_inited) |
134 #define g_logging vpxglobalm(vpxmem,g_logging) | 132 #define g_logging vpxglobalm(vpxmem,g_logging) |
135 #define memtrack vpxglobalm(vpxmem,memtrack) | 133 #define memtrack vpxglobalm(vpxmem,memtrack) |
136 #endif // #ifndef VPX_NO_GLOBALS | 134 #endif // #ifndef VPX_NO_GLOBALS |
137 | 135 |
138 extern void *vpx_malloc(size_t size); | 136 extern void *vpx_malloc(size_t size); |
139 extern void vpx_free(void *memblk); | 137 extern void vpx_free(void *memblk); |
(...skipping 10 matching lines...) Expand all Loading... |
150 vpx_memory_tracker_init(int padding_size, int pad_value) | 148 vpx_memory_tracker_init(int padding_size, int pad_value) |
151 padding_size - the size of the padding before and after each mem addr. | 149 padding_size - the size of the padding before and after each mem addr. |
152 Values > 0 indicate that integrity checks can be performed | 150 Values > 0 indicate that integrity checks can be performed |
153 by inspecting these areas. | 151 by inspecting these areas. |
154 pad_value - the initial value within the padding area before and after | 152 pad_value - the initial value within the padding area before and after |
155 each mem addr. | 153 each mem addr. |
156 | 154 |
157 Initializes global memory tracker structure | 155 Initializes global memory tracker structure |
158 Allocates the head of the list | 156 Allocates the head of the list |
159 */ | 157 */ |
160 int vpx_memory_tracker_init(int padding_size, int pad_value) | 158 int vpx_memory_tracker_init(int padding_size, int pad_value) { |
161 { | 159 if (!g_b_mem_tracker_inited) { |
162 if (!g_b_mem_tracker_inited) | 160 if ((memtrack.head = (struct mem_block *) |
163 { | 161 MEM_TRACK_MALLOC(sizeof(struct mem_block)))) { |
164 if ((memtrack.head = (struct mem_block *) | 162 int ret; |
165 MEM_TRACK_MALLOC(sizeof(struct mem_block)))) | |
166 { | |
167 int ret; | |
168 | 163 |
169 MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block)); | 164 MEM_TRACK_MEMSET(memtrack.head, 0, sizeof(struct mem_block)); |
170 | 165 |
171 memtrack.tail = memtrack.head; | 166 memtrack.tail = memtrack.head; |
172 | 167 |
173 memtrack.current_allocated = 0; | 168 memtrack.current_allocated = 0; |
174 memtrack.max_allocated = 0; | 169 memtrack.max_allocated = 0; |
175 | 170 |
176 memtrack.padding_size = padding_size; | 171 memtrack.padding_size = padding_size; |
177 memtrack.pad_value = pad_value; | 172 memtrack.pad_value = pad_value; |
178 | 173 |
179 #if HAVE_PTHREAD_H | 174 #if HAVE_PTHREAD_H |
180 ret = pthread_mutex_init(&memtrack.mutex, | 175 ret = pthread_mutex_init(&memtrack.mutex, |
181 NULL); /*mutex attributes (NULL=
default)*/ | 176 NULL); /*mutex attributes (NULL=defaul
t)*/ |
182 #elif defined(WIN32) || defined(_WIN32_WCE) | 177 #elif defined(WIN32) || defined(_WIN32_WCE) |
183 memtrack.mutex = CreateMutex(NULL, /*security attributes*/ | 178 memtrack.mutex = CreateMutex(NULL, /*security attributes*/ |
184 FALSE, /*we don't want initial owners
hip*/ | 179 FALSE, /*we don't want initial ownership*/ |
185 NULL); /*mutex name*/ | 180 NULL); /*mutex name*/ |
186 ret = !memtrack.mutex; | 181 ret = !memtrack.mutex; |
187 #elif defined(VXWORKS) | 182 #elif defined(VXWORKS) |
188 memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority b
ased mutex*/ | 183 memtrack.mutex = sem_bcreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based m
utex*/ |
189 SEM_FULL); /*SEM_FULL initial state is
unlocked*/ | 184 SEM_FULL); /*SEM_FULL initial state is unloc
ked*/ |
190 ret = !memtrack.mutex; | 185 ret = !memtrack.mutex; |
191 #elif defined(NO_MUTEX) | 186 #elif defined(NO_MUTEX) |
192 ret = 0; | 187 ret = 0; |
193 #endif | 188 #endif |
194 | 189 |
195 if (ret) | 190 if (ret) { |
196 { | 191 memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n"); |
197 memtrack_log("vpx_memory_tracker_init: Error creating mutex!\n")
; | |
198 | 192 |
199 MEM_TRACK_FREE(memtrack.head); | 193 MEM_TRACK_FREE(memtrack.head); |
200 memtrack.head = NULL; | 194 memtrack.head = NULL; |
201 } | 195 } else { |
202 else | 196 memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version" pad_siz
e:%d pad_val:0x%x %d\n" |
203 { | 197 , padding_size |
204 memtrack_log("Memory Tracker init'd, v."vpx_mem_tracker_version"
pad_size:%d pad_val:0x%x %d\n" | 198 , pad_value |
205 , padding_size | 199 , pad_value); |
206 , pad_value | 200 g_b_mem_tracker_inited = 1; |
207 , pad_value); | 201 } |
208 g_b_mem_tracker_inited = 1; | |
209 } | |
210 } | |
211 } | 202 } |
| 203 } |
212 | 204 |
213 return g_b_mem_tracker_inited; | 205 return g_b_mem_tracker_inited; |
214 } | 206 } |
215 | 207 |
216 /* | 208 /* |
217 vpx_memory_tracker_destroy() | 209 vpx_memory_tracker_destroy() |
218 If our global struct was initialized zeros out all its members, | 210 If our global struct was initialized zeros out all its members, |
219 frees memory and destroys it's mutex | 211 frees memory and destroys it's mutex |
220 */ | 212 */ |
221 void vpx_memory_tracker_destroy() | 213 void vpx_memory_tracker_destroy() { |
222 { | 214 if (!memory_tracker_lock_mutex()) { |
223 if (!memory_tracker_lock_mutex()) | 215 struct mem_block *p = memtrack.head, |
224 { | 216 * p2 = memtrack.head; |
225 struct mem_block *p = memtrack.head, | |
226 * p2 = memtrack.head; | |
227 | 217 |
228 memory_tracker_dump(); | 218 memory_tracker_dump(); |
229 | 219 |
230 while (p) | 220 while (p) { |
231 { | 221 p2 = p; |
232 p2 = p; | 222 p = p->next; |
233 p = p->next; | |
234 | 223 |
235 MEM_TRACK_FREE(p2); | 224 MEM_TRACK_FREE(p2); |
236 } | 225 } |
237 | 226 |
238 memtrack.head = NULL; | 227 memtrack.head = NULL; |
239 memtrack.tail = NULL; | 228 memtrack.tail = NULL; |
240 memtrack.len = 0; | 229 memtrack.len = 0; |
241 memtrack.current_allocated = 0; | 230 memtrack.current_allocated = 0; |
242 memtrack.max_allocated = 0; | 231 memtrack.max_allocated = 0; |
243 | 232 |
244 if (!g_logging.type && g_logging.file && g_logging.file != stderr) | 233 if (!g_logging.type && g_logging.file && g_logging.file != stderr) { |
245 { | 234 fclose(g_logging.file); |
246 fclose(g_logging.file); | 235 g_logging.file = NULL; |
247 g_logging.file = NULL; | 236 } |
248 } | |
249 | 237 |
250 memory_tracker_unlock_mutex(); | 238 memory_tracker_unlock_mutex(); |
251 | 239 |
252 g_b_mem_tracker_inited = 0; | 240 g_b_mem_tracker_inited = 0; |
253 } | 241 } |
254 } | 242 } |
255 | 243 |
256 /* | 244 /* |
257 vpx_memory_tracker_add(size_t addr, unsigned int size, | 245 vpx_memory_tracker_add(size_t addr, unsigned int size, |
258 char * file, unsigned int line) | 246 char * file, unsigned int line) |
259 addr - memory address to be added to list | 247 addr - memory address to be added to list |
260 size - size of addr | 248 size - size of addr |
261 file - the file addr was referenced from | 249 file - the file addr was referenced from |
262 line - the line in file addr was referenced from | 250 line - the line in file addr was referenced from |
263 Adds memory address addr, it's size, file and line it came from | 251 Adds memory address addr, it's size, file and line it came from |
264 to the global list via the thread safe internal library function | 252 to the global list via the thread safe internal library function |
265 */ | 253 */ |
266 void vpx_memory_tracker_add(size_t addr, unsigned int size, | 254 void vpx_memory_tracker_add(size_t addr, unsigned int size, |
267 char *file, unsigned int line, | 255 char *file, unsigned int line, |
268 int padded) | 256 int padded) { |
269 { | 257 memory_tracker_add(addr, size, file, line, padded); |
270 memory_tracker_add(addr, size, file, line, padded); | |
271 } | 258 } |
272 | 259 |
273 /* | 260 /* |
274 vpx_memory_tracker_remove(size_t addr) | 261 vpx_memory_tracker_remove(size_t addr) |
275 addr - memory address to be removed from list | 262 addr - memory address to be removed from list |
276 Removes addr from the global list via the thread safe | 263 Removes addr from the global list via the thread safe |
277 internal remove function | 264 internal remove function |
278 Return: | 265 Return: |
279 Same as described for memory_tracker_remove | 266 Same as described for memory_tracker_remove |
280 */ | 267 */ |
281 int vpx_memory_tracker_remove(size_t addr) | 268 int vpx_memory_tracker_remove(size_t addr) { |
282 { | 269 return memory_tracker_remove(addr); |
283 return memory_tracker_remove(addr); | |
284 } | 270 } |
285 | 271 |
286 /* | 272 /* |
287 vpx_memory_tracker_find(size_t addr) | 273 vpx_memory_tracker_find(size_t addr) |
288 addr - address to be found in list | 274 addr - address to be found in list |
289 Return: | 275 Return: |
290 If found, pointer to the memory block that matches addr | 276 If found, pointer to the memory block that matches addr |
291 NULL otherwise | 277 NULL otherwise |
292 */ | 278 */ |
293 struct mem_block *vpx_memory_tracker_find(size_t addr) | 279 struct mem_block *vpx_memory_tracker_find(size_t addr) { |
294 { | 280 struct mem_block *p = NULL; |
295 struct mem_block *p = NULL; | |
296 | 281 |
297 if (!memory_tracker_lock_mutex()) | 282 if (!memory_tracker_lock_mutex()) { |
298 { | 283 p = memory_tracker_find(addr); |
299 p = memory_tracker_find(addr); | 284 memory_tracker_unlock_mutex(); |
300 memory_tracker_unlock_mutex(); | 285 } |
301 } | |
302 | 286 |
303 return p; | 287 return p; |
304 } | 288 } |
305 | 289 |
306 /* | 290 /* |
307 vpx_memory_tracker_dump() | 291 vpx_memory_tracker_dump() |
308 Locks the memory tracker's mutex and calls the internal | 292 Locks the memory tracker's mutex and calls the internal |
309 library function to dump the current contents of the | 293 library function to dump the current contents of the |
310 global memory allocation list | 294 global memory allocation list |
311 */ | 295 */ |
312 void vpx_memory_tracker_dump() | 296 void vpx_memory_tracker_dump() { |
313 { | 297 if (!memory_tracker_lock_mutex()) { |
314 if (!memory_tracker_lock_mutex()) | 298 memory_tracker_dump(); |
315 { | 299 memory_tracker_unlock_mutex(); |
316 memory_tracker_dump(); | 300 } |
317 memory_tracker_unlock_mutex(); | |
318 } | |
319 } | 301 } |
320 | 302 |
321 /* | 303 /* |
322 vpx_memory_tracker_check_integrity(char* file, unsigned int line) | 304 vpx_memory_tracker_check_integrity(char* file, unsigned int line) |
323 file - The file name where the check was placed | 305 file - The file name where the check was placed |
324 line - The line in file where the check was placed | 306 line - The line in file where the check was placed |
325 Locks the memory tracker's mutex and calls the internal | 307 Locks the memory tracker's mutex and calls the internal |
326 integrity check function to inspect every address in the global | 308 integrity check function to inspect every address in the global |
327 memory allocation list | 309 memory allocation list |
328 */ | 310 */ |
329 void vpx_memory_tracker_check_integrity(char *file, unsigned int line) | 311 void vpx_memory_tracker_check_integrity(char *file, unsigned int line) { |
330 { | 312 if (!memory_tracker_lock_mutex()) { |
331 if (!memory_tracker_lock_mutex()) | 313 memory_tracker_check_integrity(file, line); |
332 { | 314 memory_tracker_unlock_mutex(); |
333 memory_tracker_check_integrity(file, line); | 315 } |
334 memory_tracker_unlock_mutex(); | |
335 } | |
336 } | 316 } |
337 | 317 |
338 /* | 318 /* |
339 vpx_memory_tracker_set_log_type | 319 vpx_memory_tracker_set_log_type |
340 Sets the logging type for the memory tracker. Based on the value it will | 320 Sets the logging type for the memory tracker. Based on the value it will |
341 direct its output to the appropriate place. | 321 direct its output to the appropriate place. |
342 Return: | 322 Return: |
343 0: on success | 323 0: on success |
344 -1: if the logging type could not be set, because the value was invalid | 324 -1: if the logging type could not be set, because the value was invalid |
345 or because a file could not be opened | 325 or because a file could not be opened |
346 */ | 326 */ |
347 int vpx_memory_tracker_set_log_type(int type, char *option) | 327 int vpx_memory_tracker_set_log_type(int type, char *option) { |
348 { | 328 int ret = -1; |
349 int ret = -1; | |
350 | 329 |
351 switch (type) | 330 switch (type) { |
352 { | |
353 case 0: | 331 case 0: |
354 g_logging.type = 0; | 332 g_logging.type = 0; |
355 | 333 |
356 if (!option) | 334 if (!option) { |
357 { | 335 g_logging.file = stderr; |
358 g_logging.file = stderr; | 336 ret = 0; |
359 ret = 0; | 337 } else { |
360 } | 338 if ((g_logging.file = fopen((char *)option, "w"))) |
361 else | 339 ret = 0; |
362 { | 340 } |
363 if ((g_logging.file = fopen((char *)option, "w"))) | |
364 ret = 0; | |
365 } | |
366 | 341 |
367 break; | 342 break; |
368 #if defined(WIN32) && !defined(_WIN32_WCE) | 343 #if defined(WIN32) && !defined(_WIN32_WCE) |
369 case 1: | 344 case 1: |
370 g_logging.type = type; | 345 g_logging.type = type; |
371 ret = 0; | 346 ret = 0; |
372 break; | 347 break; |
373 #endif | 348 #endif |
374 default: | 349 default: |
375 break; | 350 break; |
376 } | 351 } |
377 | 352 |
378 //output the version to the new logging destination | 353 // output the version to the new logging destination |
379 if (!ret) | 354 if (!ret) |
380 memtrack_log("Memory Tracker logging initialized, " | 355 memtrack_log("Memory Tracker logging initialized, " |
381 "Memory Tracker v."vpx_mem_tracker_version"\n"); | 356 "Memory Tracker v."vpx_mem_tracker_version"\n"); |
382 | 357 |
383 return ret; | 358 return ret; |
384 } | 359 } |
385 | 360 |
386 /* | 361 /* |
387 vpx_memory_tracker_set_log_func | 362 vpx_memory_tracker_set_log_func |
388 Sets a logging function to be used by the memory tracker. | 363 Sets a logging function to be used by the memory tracker. |
389 Return: | 364 Return: |
390 0: on success | 365 0: on success |
391 -1: if the logging type could not be set because logfunc was NULL | 366 -1: if the logging type could not be set because logfunc was NULL |
392 */ | 367 */ |
393 int vpx_memory_tracker_set_log_func(void *userdata, | 368 int vpx_memory_tracker_set_log_func(void *userdata, |
394 void(*logfunc)(void *userdata, | 369 void(*logfunc)(void *userdata, |
395 const char *fmt, va_list args)) | 370 const char *fmt, va_list args
)) { |
396 { | 371 int ret = -1; |
397 int ret = -1; | |
398 | 372 |
399 if (logfunc) | 373 if (logfunc) { |
400 { | 374 g_logging.type = -1; |
401 g_logging.type = -1; | 375 g_logging.userdata = userdata; |
402 g_logging.userdata = userdata; | 376 g_logging.func = logfunc; |
403 g_logging.func = logfunc; | 377 ret = 0; |
404 ret = 0; | 378 } |
405 } | |
406 | 379 |
407 //output the version to the new logging destination | 380 // output the version to the new logging destination |
408 if (!ret) | 381 if (!ret) |
409 memtrack_log("Memory Tracker logging initialized, " | 382 memtrack_log("Memory Tracker logging initialized, " |
410 "Memory Tracker v."vpx_mem_tracker_version"\n"); | 383 "Memory Tracker v."vpx_mem_tracker_version"\n"); |
411 | 384 |
412 return ret; | 385 return ret; |
413 } | 386 } |
414 | 387 |
415 /* | 388 /* |
416 * | 389 * |
417 * END - Exposed library functions | 390 * END - Exposed library functions |
418 * | 391 * |
419 */ | 392 */ |
420 | 393 |
421 | 394 |
422 /* | 395 /* |
423 * | 396 * |
424 * Internal library functions | 397 * Internal library functions |
425 * | 398 * |
426 */ | 399 */ |
427 | 400 |
428 static void memtrack_log(const char *fmt, ...) | 401 static void memtrack_log(const char *fmt, ...) { |
429 { | 402 va_list list; |
430 va_list list; | |
431 | 403 |
432 va_start(list, fmt); | 404 va_start(list, fmt); |
433 | 405 |
434 switch (g_logging.type) | 406 switch (g_logging.type) { |
435 { | |
436 case -1: | 407 case -1: |
437 | 408 |
438 if (g_logging.func) | 409 if (g_logging.func) |
439 g_logging.func(g_logging.userdata, fmt, list); | 410 g_logging.func(g_logging.userdata, fmt, list); |
440 | 411 |
441 break; | 412 break; |
442 case 0: | 413 case 0: |
443 | 414 |
444 if (g_logging.file) | 415 if (g_logging.file) { |
445 { | 416 vfprintf(g_logging.file, fmt, list); |
446 vfprintf(g_logging.file, fmt, list); | 417 fflush(g_logging.file); |
447 fflush(g_logging.file); | 418 } |
448 } | |
449 | 419 |
450 break; | 420 break; |
451 #if defined(WIN32) && !defined(_WIN32_WCE) | 421 #if defined(WIN32) && !defined(_WIN32_WCE) |
452 case 1: | 422 case 1: { |
453 { | 423 char temp[1024]; |
454 char temp[1024]; | 424 _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list); |
455 _vsnprintf(temp, sizeof(temp) / sizeof(char) - 1, fmt, list); | 425 OutputDebugString(temp); |
456 OutputDebugString(temp); | |
457 } | 426 } |
458 break; | 427 break; |
459 #endif | 428 #endif |
460 default: | 429 default: |
461 break; | 430 break; |
462 } | 431 } |
463 | 432 |
464 va_end(list); | 433 va_end(list); |
465 } | 434 } |
466 | 435 |
467 /* | 436 /* |
468 memory_tracker_dump() | 437 memory_tracker_dump() |
469 Dumps the current contents of the global memory allocation list | 438 Dumps the current contents of the global memory allocation list |
470 */ | 439 */ |
471 static void memory_tracker_dump() | 440 static void memory_tracker_dump() { |
472 { | 441 int i = 0; |
473 int i = 0; | 442 struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL); |
474 struct mem_block *p = (memtrack.head ? memtrack.head->next : NULL); | |
475 | 443 |
476 memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n", | 444 memtrack_log("\n_currently Allocated= %d; Max allocated= %d\n", |
477 memtrack.current_allocated, memtrack.max_allocated); | 445 memtrack.current_allocated, memtrack.max_allocated); |
478 | 446 |
479 while (p) | 447 while (p) { |
480 { | |
481 #if defined(WIN32) && !defined(_WIN32_WCE) | 448 #if defined(WIN32) && !defined(_WIN32_WCE) |
482 | 449 |
483 /*when using outputdebugstring, output filenames so they | 450 /*when using outputdebugstring, output filenames so they |
484 can be clicked to be opened in visual studio*/ | 451 can be clicked to be opened in visual studio*/ |
485 if (g_logging.type == 1) | 452 if (g_logging.type == 1) |
486 memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, fi
le:\n" | 453 memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file:\n" |
487 " %s(%d):\n", i, | 454 " %s(%d):\n", i, |
488 p->addr, i, p->size, | 455 p->addr, i, p->size, |
489 p->file, p->line); | 456 p->file, p->line); |
490 else | 457 else |
491 #endif | 458 #endif |
492 memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, fi
le: %s, line: %d\n", i, | 459 memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s
, line: %d\n", i, |
493 p->addr, i, p->size, | 460 p->addr, i, p->size, |
494 p->file, p->line); | 461 p->file, p->line); |
495 | 462 |
496 p = p->next; | 463 p = p->next; |
497 ++i; | 464 ++i; |
498 } | 465 } |
499 | 466 |
500 memtrack_log("\n"); | 467 memtrack_log("\n"); |
501 } | 468 } |
502 | 469 |
503 /* | 470 /* |
504 memory_tracker_check_integrity(char* file, unsigned int file) | 471 memory_tracker_check_integrity(char* file, unsigned int file) |
505 file - the file name where the check was placed | 472 file - the file name where the check was placed |
506 line - the line in file where the check was placed | 473 line - the line in file where the check was placed |
507 If a padding_size was supplied to vpx_memory_tracker_init() | 474 If a padding_size was supplied to vpx_memory_tracker_init() |
508 this function will check ea. addr in the list verifying that | 475 this function will check ea. addr in the list verifying that |
509 addr-padding_size and addr+padding_size is filled with pad_value | 476 addr-padding_size and addr+padding_size is filled with pad_value |
510 */ | 477 */ |
511 static void memory_tracker_check_integrity(char *file, unsigned int line) | 478 static void memory_tracker_check_integrity(char *file, unsigned int line) { |
512 { | 479 if (memtrack.padding_size) { |
513 if (memtrack.padding_size) | 480 int i, |
514 { | 481 index = 0; |
515 int i, | 482 unsigned char *p_show_me, |
516 index = 0; | 483 * p_show_me2; |
517 unsigned char *p_show_me, | 484 unsigned int tempme = memtrack.pad_value, |
518 * p_show_me2; | 485 dead1, |
519 unsigned int tempme = memtrack.pad_value, | 486 dead2; |
520 dead1, | 487 unsigned char *x_bounds; |
521 dead2; | 488 struct mem_block *p = memtrack.head->next; |
522 unsigned char *x_bounds; | |
523 struct mem_block *p = memtrack.head->next; | |
524 | 489 |
525 while (p) | 490 while (p) { |
526 { | 491 // x_bounds = (unsigned char*)p->addr; |
527 //x_bounds = (unsigned char*)p->addr; | 492 // back up VPX_BYTE_ALIGNMENT |
528 //back up VPX_BYTE_ALIGNMENT | 493 // x_bounds -= memtrack.padding_size; |
529 //x_bounds -= memtrack.padding_size; | |
530 | 494 |
531 if (p->padded) // can the bounds be checked? | 495 if (p->padded) { // can the bounds be checked? |
532 { | 496 /*yes, move to the address that was actually allocated |
533 /*yes, move to the address that was actually allocated | 497 by the vpx_* calls*/ |
534 by the vpx_* calls*/ | 498 x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]); |
535 x_bounds = (unsigned char *)(((size_t *)p->addr)[-1]); | |
536 | 499 |
537 for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int)
) | 500 for (i = 0; i < memtrack.padding_size; i += sizeof(unsigned int)) { |
538 { | 501 p_show_me = (x_bounds + i); |
539 p_show_me = (x_bounds + i); | 502 p_show_me2 = (unsigned char *)(p->addr + p->size + i); |
540 p_show_me2 = (unsigned char *)(p->addr + p->size + i); | |
541 | 503 |
542 MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int)); | 504 MEM_TRACK_MEMCPY(&dead1, p_show_me, sizeof(unsigned int)); |
543 MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int)); | 505 MEM_TRACK_MEMCPY(&dead2, p_show_me2, sizeof(unsigned int)); |
544 | 506 |
545 if ((dead1 != tempme) || (dead2 != tempme)) | 507 if ((dead1 != tempme) || (dead2 != tempme)) { |
546 { | 508 memtrack_log("\n[vpx_mem integrity check failed]:\n" |
547 memtrack_log("\n[vpx_mem integrity check failed]:\n" | 509 " index[%d,%d] {%s:%d} addr=0x%x, size=%d," |
548 " index[%d,%d] {%s:%d} addr=0x%x, size=%
d," | 510 " file: %s, line: %d c0:0x%x c1:0x%x\n", |
549 " file: %s, line: %d c0:0x%x c1:0x%x\n", | 511 index, i, file, line, p->addr, p->size, p->file, |
550 index, i, file, line, p->addr, p->size, p->
file, | 512 p->line, dead1, dead2); |
551 p->line, dead1, dead2); | 513 } |
552 } | 514 } |
553 } | 515 } |
554 } | |
555 | 516 |
556 ++index; | 517 ++index; |
557 p = p->next; | 518 p = p->next; |
558 } | |
559 } | 519 } |
| 520 } |
560 } | 521 } |
561 | 522 |
562 /* | 523 /* |
563 memory_tracker_add(size_t addr, unsigned int size, | 524 memory_tracker_add(size_t addr, unsigned int size, |
564 char * file, unsigned int line) | 525 char * file, unsigned int line) |
565 Adds an address (addr), it's size, file and line number to our list. | 526 Adds an address (addr), it's size, file and line number to our list. |
566 Adjusts the total bytes allocated and max bytes allocated if necessary. | 527 Adjusts the total bytes allocated and max bytes allocated if necessary. |
567 If memory cannot be allocated the list will be destroyed. | 528 If memory cannot be allocated the list will be destroyed. |
568 */ | 529 */ |
569 void memory_tracker_add(size_t addr, unsigned int size, | 530 void memory_tracker_add(size_t addr, unsigned int size, |
570 char *file, unsigned int line, | 531 char *file, unsigned int line, |
571 int padded) | 532 int padded) { |
572 { | 533 if (!memory_tracker_lock_mutex()) { |
573 if (!memory_tracker_lock_mutex()) | 534 struct mem_block *p; |
574 { | |
575 struct mem_block *p; | |
576 | 535 |
577 p = MEM_TRACK_MALLOC(sizeof(struct mem_block)); | 536 p = MEM_TRACK_MALLOC(sizeof(struct mem_block)); |
578 | 537 |
579 if (p) | 538 if (p) { |
580 { | 539 p->prev = memtrack.tail; |
581 p->prev = memtrack.tail; | 540 p->prev->next = p; |
582 p->prev->next = p; | 541 p->addr = addr; |
583 p->addr = addr; | 542 p->size = size; |
584 p->size = size; | 543 p->line = line; |
585 p->line = line; | 544 p->file = file; |
586 p->file = file; | 545 p->padded = padded; |
587 p->padded = padded; | 546 p->next = NULL; |
588 p->next = NULL; | |
589 | 547 |
590 memtrack.tail = p; | 548 memtrack.tail = p; |
591 | 549 |
592 memtrack.current_allocated += size; | 550 memtrack.current_allocated += size; |
593 | 551 |
594 if (memtrack.current_allocated > memtrack.max_allocated) | 552 if (memtrack.current_allocated > memtrack.max_allocated) |
595 memtrack.max_allocated = memtrack.current_allocated; | 553 memtrack.max_allocated = memtrack.current_allocated; |
596 | 554 |
597 //memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr); | 555 // memtrack_log("memory_tracker_add: added addr=0x%.8x\n", addr); |
598 | 556 |
599 memory_tracker_unlock_mutex(); | 557 memory_tracker_unlock_mutex(); |
600 } | 558 } else { |
601 else | 559 memtrack_log("memory_tracker_add: error allocating memory!\n"); |
602 { | 560 memory_tracker_unlock_mutex(); |
603 memtrack_log("memory_tracker_add: error allocating memory!\n"); | 561 vpx_memory_tracker_destroy(); |
604 memory_tracker_unlock_mutex(); | |
605 vpx_memory_tracker_destroy(); | |
606 } | |
607 } | 562 } |
| 563 } |
608 } | 564 } |
609 | 565 |
610 /* | 566 /* |
611 memory_tracker_remove(size_t addr) | 567 memory_tracker_remove(size_t addr) |
612 Removes an address and its corresponding size (if they exist) | 568 Removes an address and its corresponding size (if they exist) |
613 from the memory tracker list and adjusts the current number | 569 from the memory tracker list and adjusts the current number |
614 of bytes allocated. | 570 of bytes allocated. |
615 Return: | 571 Return: |
616 0: on success | 572 0: on success |
617 -1: if the mutex could not be locked | 573 -1: if the mutex could not be locked |
618 -2: if the addr was not found in the list | 574 -2: if the addr was not found in the list |
619 */ | 575 */ |
620 int memory_tracker_remove(size_t addr) | 576 int memory_tracker_remove(size_t addr) { |
621 { | 577 int ret = -1; |
622 int ret = -1; | |
623 | 578 |
624 if (!memory_tracker_lock_mutex()) | 579 if (!memory_tracker_lock_mutex()) { |
625 { | 580 struct mem_block *p; |
626 struct mem_block *p; | |
627 | 581 |
628 if ((p = memory_tracker_find(addr))) | 582 if ((p = memory_tracker_find(addr))) { |
629 { | 583 memtrack.current_allocated -= p->size; |
630 memtrack.current_allocated -= p->size; | |
631 | 584 |
632 p->prev->next = p->next; | 585 p->prev->next = p->next; |
633 | 586 |
634 if (p->next) | 587 if (p->next) |
635 p->next->prev = p->prev; | 588 p->next->prev = p->prev; |
636 else | 589 else |
637 memtrack.tail = p->prev; | 590 memtrack.tail = p->prev; |
638 | 591 |
639 ret = 0; | 592 ret = 0; |
640 MEM_TRACK_FREE(p); | 593 MEM_TRACK_FREE(p); |
641 } | 594 } else { |
642 else | 595 if (addr) |
643 { | 596 memtrack_log("memory_tracker_remove(): addr not found in list," |
644 if (addr) | 597 " 0x%.8x\n", addr); |
645 memtrack_log("memory_tracker_remove(): addr not found in list," | |
646 " 0x%.8x\n", addr); | |
647 | 598 |
648 ret = -2; | 599 ret = -2; |
649 } | |
650 | |
651 memory_tracker_unlock_mutex(); | |
652 } | 600 } |
653 | 601 |
654 return ret; | 602 memory_tracker_unlock_mutex(); |
| 603 } |
| 604 |
| 605 return ret; |
655 } | 606 } |
656 | 607 |
657 /* | 608 /* |
658 memory_tracker_find(size_t addr) | 609 memory_tracker_find(size_t addr) |
659 Finds an address in our addrs list | 610 Finds an address in our addrs list |
660 NOTE: the mutex MUST be locked in the other internal | 611 NOTE: the mutex MUST be locked in the other internal |
661 functions before calling this one. This avoids | 612 functions before calling this one. This avoids |
662 the need for repeated locking and unlocking as in Remove | 613 the need for repeated locking and unlocking as in Remove |
663 Returns: pointer to the mem block if found, NULL otherwise | 614 Returns: pointer to the mem block if found, NULL otherwise |
664 */ | 615 */ |
665 static struct mem_block *memory_tracker_find(size_t addr) | 616 static struct mem_block *memory_tracker_find(size_t addr) { |
666 { | 617 struct mem_block *p = NULL; |
667 struct mem_block *p = NULL; | |
668 | 618 |
669 if (memtrack.head) | 619 if (memtrack.head) { |
670 { | 620 p = memtrack.head->next; |
671 p = memtrack.head->next; | |
672 | 621 |
673 while (p && (p->addr != addr)) | 622 while (p && (p->addr != addr)) |
674 p = p->next; | 623 p = p->next; |
675 } | 624 } |
676 | 625 |
677 return p; | 626 return p; |
678 } | 627 } |
679 | 628 |
680 | 629 |
681 #if !defined(NO_MUTEX) | 630 #if !defined(NO_MUTEX) |
682 /* | 631 /* |
683 memory_tracker_lock_mutex() | 632 memory_tracker_lock_mutex() |
684 Locks the memory tracker mutex with a platform specific call | 633 Locks the memory tracker mutex with a platform specific call |
685 Returns: | 634 Returns: |
686 0: Success | 635 0: Success |
687 <0: Failure, either the mutex was not initialized | 636 <0: Failure, either the mutex was not initialized |
688 or the call to lock the mutex failed | 637 or the call to lock the mutex failed |
689 */ | 638 */ |
690 static int memory_tracker_lock_mutex() | 639 static int memory_tracker_lock_mutex() { |
691 { | 640 int ret = -1; |
692 int ret = -1; | |
693 | 641 |
694 if (g_b_mem_tracker_inited) | 642 if (g_b_mem_tracker_inited) { |
695 { | |
696 | 643 |
697 #if HAVE_PTHREAD_H | 644 #if HAVE_PTHREAD_H |
698 ret = pthread_mutex_lock(&memtrack.mutex); | 645 ret = pthread_mutex_lock(&memtrack.mutex); |
699 #elif defined(WIN32) || defined(_WIN32_WCE) | 646 #elif defined(WIN32) || defined(_WIN32_WCE) |
700 ret = WaitForSingleObject(memtrack.mutex, INFINITE); | 647 ret = WaitForSingleObject(memtrack.mutex, INFINITE); |
701 #elif defined(VXWORKS) | 648 #elif defined(VXWORKS) |
702 ret = sem_take(memtrack.mutex, WAIT_FOREVER); | 649 ret = sem_take(memtrack.mutex, WAIT_FOREVER); |
703 #endif | 650 #endif |
704 | 651 |
705 if (ret) | 652 if (ret) { |
706 { | 653 memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n"); |
707 memtrack_log("memory_tracker_lock_mutex: mutex lock failed\n"); | |
708 } | |
709 } | 654 } |
| 655 } |
710 | 656 |
711 return ret; | 657 return ret; |
712 } | 658 } |
713 | 659 |
714 /* | 660 /* |
715 memory_tracker_unlock_mutex() | 661 memory_tracker_unlock_mutex() |
716 Unlocks the memory tracker mutex with a platform specific call | 662 Unlocks the memory tracker mutex with a platform specific call |
717 Returns: | 663 Returns: |
718 0: Success | 664 0: Success |
719 <0: Failure, either the mutex was not initialized | 665 <0: Failure, either the mutex was not initialized |
720 or the call to unlock the mutex failed | 666 or the call to unlock the mutex failed |
721 */ | 667 */ |
722 static int memory_tracker_unlock_mutex() | 668 static int memory_tracker_unlock_mutex() { |
723 { | 669 int ret = -1; |
724 int ret = -1; | |
725 | 670 |
726 if (g_b_mem_tracker_inited) | 671 if (g_b_mem_tracker_inited) { |
727 { | |
728 | 672 |
729 #if HAVE_PTHREAD_H | 673 #if HAVE_PTHREAD_H |
730 ret = pthread_mutex_unlock(&memtrack.mutex); | 674 ret = pthread_mutex_unlock(&memtrack.mutex); |
731 #elif defined(WIN32) || defined(_WIN32_WCE) | 675 #elif defined(WIN32) || defined(_WIN32_WCE) |
732 ret = !ReleaseMutex(memtrack.mutex); | 676 ret = !ReleaseMutex(memtrack.mutex); |
733 #elif defined(VXWORKS) | 677 #elif defined(VXWORKS) |
734 ret = sem_give(memtrack.mutex); | 678 ret = sem_give(memtrack.mutex); |
735 #endif | 679 #endif |
736 | 680 |
737 if (ret) | 681 if (ret) { |
738 { | 682 memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n"); |
739 memtrack_log("memory_tracker_unlock_mutex: mutex unlock failed\n"); | |
740 } | |
741 } | 683 } |
| 684 } |
742 | 685 |
743 return ret; | 686 return ret; |
744 } | 687 } |
745 #endif | 688 #endif |
746 | 689 |
747 /* | 690 /* |
748 vpx_memory_tracker_set_functions | 691 vpx_memory_tracker_set_functions |
749 | 692 |
750 Sets the function pointers for the standard library functions. | 693 Sets the function pointers for the standard library functions. |
751 | 694 |
752 Return: | 695 Return: |
753 0: on success | 696 0: on success |
754 -1: if the use global function pointers is not set. | 697 -1: if the use global function pointers is not set. |
755 */ | 698 */ |
756 int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l | 699 int vpx_memory_tracker_set_functions(mem_track_malloc_func g_malloc_l |
757 , mem_track_calloc_func g_calloc_l | 700 , mem_track_calloc_func g_calloc_l |
758 , mem_track_realloc_func g_realloc_l | 701 , mem_track_realloc_func g_realloc_l |
759 , mem_track_free_func g_free_l | 702 , mem_track_free_func g_free_l |
760 , mem_track_memcpy_func g_memcpy_l | 703 , mem_track_memcpy_func g_memcpy_l |
761 , mem_track_memset_func g_memset_l | 704 , mem_track_memset_func g_memset_l |
762 , mem_track_memmove_func g_memmove_l) | 705 , mem_track_memmove_func g_memmove_l) { |
763 { | |
764 #if USE_GLOBAL_FUNCTION_POINTERS | 706 #if USE_GLOBAL_FUNCTION_POINTERS |
765 | 707 |
766 if (g_malloc_l) | 708 if (g_malloc_l) |
767 g_malloc = g_malloc_l; | 709 g_malloc = g_malloc_l; |
768 | 710 |
769 if (g_calloc_l) | 711 if (g_calloc_l) |
770 g_calloc = g_calloc_l; | 712 g_calloc = g_calloc_l; |
771 | 713 |
772 if (g_realloc_l) | 714 if (g_realloc_l) |
773 g_realloc = g_realloc_l; | 715 g_realloc = g_realloc_l; |
774 | 716 |
775 if (g_free_l) | 717 if (g_free_l) |
776 g_free = g_free_l; | 718 g_free = g_free_l; |
777 | 719 |
778 if (g_memcpy_l) | 720 if (g_memcpy_l) |
779 g_memcpy = g_memcpy_l; | 721 g_memcpy = g_memcpy_l; |
780 | 722 |
781 if (g_memset_l) | 723 if (g_memset_l) |
782 g_memset = g_memset_l; | 724 g_memset = g_memset_l; |
783 | 725 |
784 if (g_memmove_l) | 726 if (g_memmove_l) |
785 g_memmove = g_memmove_l; | 727 g_memmove = g_memmove_l; |
786 | 728 |
787 return 0; | 729 return 0; |
788 #else | 730 #else |
789 (void)g_malloc_l; | 731 (void)g_malloc_l; |
790 (void)g_calloc_l; | 732 (void)g_calloc_l; |
791 (void)g_realloc_l; | 733 (void)g_realloc_l; |
792 (void)g_free_l; | 734 (void)g_free_l; |
793 (void)g_memcpy_l; | 735 (void)g_memcpy_l; |
794 (void)g_memset_l; | 736 (void)g_memset_l; |
795 (void)g_memmove_l; | 737 (void)g_memmove_l; |
796 return -1; | 738 return -1; |
797 #endif | 739 #endif |
798 } | 740 } |
OLD | NEW |