1 /*
2 * default memory allocator for libavutil
3 * Copyright (c) 2002 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * default memory allocator for libavutil
25 */
26
27 #define _XOPEN_SOURCE 600
28
29 #include "config.h"
30
32 #include <stdint.h>
33 #include <stdlib.h>
34 #include <stdatomic.h>
35 #include <string.h>
36 #if HAVE_MALLOC_H
37 #include <malloc.h>
38 #endif
39
48
49 #ifdef MALLOC_PREFIX
50
51 #define malloc AV_JOIN(MALLOC_PREFIX, malloc)
52 #define memalign AV_JOIN(MALLOC_PREFIX, memalign)
53 #define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
54 #define realloc AV_JOIN(MALLOC_PREFIX, realloc)
55 #define free AV_JOIN(MALLOC_PREFIX, free)
56
57 void *malloc(
size_t size);
58 void *memalign(
size_t align,
size_t size);
59 int posix_memalign(
void **ptr,
size_t align,
size_t size);
60 void *realloc(
void *ptr,
size_t size);
61 void free(void *ptr);
62
63 #endif /* MALLOC_PREFIX */
64
65 #define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : (HAVE_SIMD_ALIGN_32 ? 32 : 16))
66
67 #define FF_MEMORY_POISON 0x2a
68
69 /* NOTE: if you want to override these functions with your own
70 * implementations (not recommended) you have to link libav* as
71 * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
72 * Note that this will cost performance. */
73
75
78 }
79
81 {
82 size_t t;
83
84 #if (!defined(__INTEL_COMPILER) && AV_GCC_VERSION_AT_LEAST(5,1)) || AV_HAS_BUILTIN(__builtin_mul_overflow)
85 if (__builtin_mul_overflow(
a,
b, &t))
87 #else
89 /* Hack inspired from glibc: don't try the division if nelem and elsize
90 * are both less than sqrt(SIZE_MAX). */
91 if ((
a |
b) >= ((
size_t)1 << (
sizeof(
size_t) * 4)) &&
a && t /
a !=
b)
93 #endif
95 return 0;
96 }
97
99 {
101
104
105 #if HAVE_POSIX_MEMALIGN
106 if (
size)
//OS X on SDK 10.6 has a broken posix_memalign implementation
109 #elif HAVE_ALIGNED_MALLOC
111 #elif HAVE_MEMALIGN
112 #ifndef __DJGPP__
114 #else
116 #endif
117 /* Why 64?
118 * Indeed, we should align it:
119 * on 4 for 386
120 * on 16 for 486
121 * on 32 for 586, PPro - K6-III
122 * on 64 for K7 (maybe for P3 too).
123 * Because L1 and L2 caches are aligned on those values.
124 * But I don't want to code such logic here!
125 */
126 /* Why 32?
127 * For AVX ASM. SSE / NEON needs only 16.
128 * Why not larger? Because I did not see a difference in benchmarks ...
129 */
130 /* benchmarks with P3
131 * memalign(64) + 1 3071, 3051, 3032
132 * memalign(64) + 2 3051, 3032, 3041
133 * memalign(64) + 4 2911, 2896, 2915
134 * memalign(64) + 8 2545, 2554, 2550
135 * memalign(64) + 16 2543, 2572, 2563
136 * memalign(64) + 32 2546, 2545, 2571
137 * memalign(64) + 64 2570, 2533, 2558
138 *
139 * BTW, malloc seems to do 8-byte alignment by default here.
140 */
141 #else
143 #endif
147 }
148 #if CONFIG_MEMORY_POISONING
149 if (ptr)
151 #endif
152 return ptr;
153 }
154
156 {
160
161 #if HAVE_ALIGNED_MALLOC
163 #else
165 #endif
166 #if CONFIG_MEMORY_POISONING
169 #endif
171 }
172
174 {
177
181 }
186 }
187
189 {
191
194 return 0;
195 }
196
197 memcpy(&
val, ptr,
sizeof(
val));
199
203 }
204
205 memcpy(ptr, &
val,
sizeof(
val));
206 return 0;
207 }
208
210 {
215 }
216
218 {
223 }
224
226 {
228
229 memcpy(&
val, ptr,
sizeof(
val));
231 memcpy(ptr, &
val,
sizeof(
val));
234
235 return 0;
236 }
237
239 {
240 #if HAVE_ALIGNED_MALLOC
241 _aligned_free(ptr);
242 #else
243 free(ptr);
244 #endif
245 }
246
248 {
250
254 }
255
257 {
259 if (ptr)
260 memset(ptr, 0,
size);
261 return ptr;
262 }
263
265 {
270 }
271
273 {
276 size_t len = strlen(
s) + 1;
278 if (ptr)
280 }
281 return ptr;
282 }
283
285 {
287
290
291 end = memchr(
s, 0,
len);
292 if (end)
294
298
302 }
303
305 {
309 if (ptr)
310 memcpy(ptr,
p,
size);
311 }
312 return ptr;
313 }
314
316 {
318 memcpy(&
tab, tab_ptr,
sizeof(
tab));
319
322 memcpy(tab_ptr, &
tab,
sizeof(
tab));
323 }, {
325 });
326 return 0;
327 }
328
330 {
332 memcpy(&
tab, tab_ptr,
sizeof(
tab));
333
336 memcpy(tab_ptr, &
tab,
sizeof(
tab));
337 }, {
338 *nb_ptr = 0;
340 });
341 }
342
344 const uint8_t *elem_data)
345 {
346 uint8_t *tab_elem_data =
NULL;
347
349 tab_elem_data = (uint8_t *)*tab_ptr + (*nb_ptr) * elem_size;
350 if (elem_data)
351 memcpy(tab_elem_data, elem_data, elem_size);
352 else if (CONFIG_MEMORY_POISONING)
354 }, {
356 *nb_ptr = 0;
357 });
358 return tab_elem_data;
359 }
360
362 {
364
365 v |= v << 16;
366
371 }
372
376 }
377 }
378
380 {
381 #if HAVE_BIGENDIAN
383 uint32_t
a = v << 8 | v >> 16;
384 uint32_t
b = v << 16 | v >> 8;
385 uint32_t
c = v << 24 | v;
386 #else
388 uint32_t
a = v | v << 24;
389 uint32_t
b = v >> 8 | v << 16;
390 uint32_t
c = v >> 16 | v << 8;
391 #endif
392
399 }
400
405 }
406
411 }
412
416 }
417 }
418
420 {
422
423 #if HAVE_FAST_64BIT
424 uint64_t v2= v + ((uint64_t)v<<32);
432 }
433 #endif
434
439 }
440
444 }
445 }
446
448 {
449 const uint8_t *
src = &
dst[-back];
450 if (!back)
451 return;
452
453 if (back == 1) {
455 } else if (back == 2) {
457 } else if (back == 3) {
459 } else if (back == 4) {
461 } else {
462 if (cnt >= 16) {
463 int blocklen = back;
464 while (cnt > blocklen) {
465 memcpy(
dst,
src, blocklen);
467 cnt -= blocklen;
468 blocklen <<= 1;
469 }
471 return;
472 }
473 if (cnt >= 8) {
478 cnt -= 8;
479 }
480 if (cnt >= 4) {
484 cnt -= 4;
485 }
486 if (cnt >= 2) {
490 cnt -= 2;
491 }
492 if (cnt)
494 }
495 }
496
498 {
499 size_t max_size;
500
501 if (min_size <= *
size)
502 return ptr;
503
505 /* *size is an unsigned, so the real maximum is <= UINT_MAX. */
506 max_size =
FFMIN(max_size, UINT_MAX);
507
508 if (min_size > max_size) {
511 }
512
513 min_size =
FFMIN(max_size,
FFMAX(min_size + min_size / 16 + 32, min_size));
514
516 /* we could set this to the unmodified min_size but this is safer
517 * if the user lost the ptr and uses NULL now
518 */
519 if (!ptr)
520 min_size = 0;
521
523
524 return ptr;
525 }
526
527 static inline void fast_malloc(
void *ptr,
unsigned int *
size,
size_t min_size,
int zero_realloc)
528 {
529 size_t max_size;
531
532 memcpy(&
val, ptr,
sizeof(
val));
533 if (min_size <= *
size) {
535 return;
536 }
537
539 /* *size is an unsigned, so the real maximum is <= UINT_MAX. */
540 max_size =
FFMIN(max_size, UINT_MAX);
541
542 if (min_size > max_size) {
545 return;
546 }
547 min_size =
FFMIN(max_size,
FFMAX(min_size + min_size / 16 + 32, min_size));
550 memcpy(ptr, &
val,
sizeof(
val));
552 min_size = 0;
554 return;
555 }
556
558 {
560 }
561
563 {
565 }
566
568 {
570 }