Directly #include a bunch of indirectly #included headers.
[libav.git] / libavutil / mem.c
CommitLineData
d01fe86d 1/*
cea8f6f3 2 * default memory allocator for libavutil
406792e7 3 * Copyright (c) 2002 Fabrice Bellard
d01fe86d 4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
d01fe86d
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
d01fe86d 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
d01fe86d
FB
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
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d01fe86d 20 */
115329f1 21
983e3246
MN
22/**
23 * @file mem.c
cea8f6f3 24 * default memory allocator for libavutil.
983e3246 25 */
115329f1 26
dfcb6b56 27#include "config.h"
cea8f6f3 28#include "common.h"
8e1e6f31 29
eafcac6a 30/* here we can use OS dependent allocation functions */
8e1e6f31
FB
31#undef malloc
32#undef free
33#undef realloc
34
dfcb6b56 35#include <limits.h>
1f91cdce 36#include <stdlib.h>
dfcb6b56 37#include <string.h>
b250f9c6 38#if HAVE_MALLOC_H
d01fe86d
FB
39#include <malloc.h>
40#endif
41
42/* you can redefine av_malloc and av_free in your project to use your
43 memory allocator. You do not need to suppress this file because the
44 linker will do it automatically */
45
18f77016 46void *av_malloc(unsigned int size)
d01fe86d 47{
1f91cdce 48 void *ptr = NULL;
b250f9c6 49#if CONFIG_MEMALIGN_HACK
ed96aeea 50 long diff;
88730be6 51#endif
0ecca7a4 52
7d77d5f6 53 /* let's disallow possible ambiguous cases */
0a7c36af 54 if(size > (INT_MAX-16) )
0ecca7a4 55 return NULL;
115329f1 56
b250f9c6 57#if CONFIG_MEMALIGN_HACK
a9493601
H
58 ptr = malloc(size+16);
59 if(!ptr)
60 return ptr;
ed96aeea 61 diff= ((-(long)ptr - 1)&15) + 1;
90d30570 62 ptr = (char*)ptr + diff;
da9b170c 63 ((char*)ptr)[-1]= diff;
b250f9c6 64#elif HAVE_POSIX_MEMALIGN
1f91cdce 65 posix_memalign(&ptr,16,size);
b250f9c6 66#elif HAVE_MEMALIGN
8f2b21a8 67 ptr = memalign(16,size);
115329f1 68 /* Why 64?
d01fe86d
FB
69 Indeed, we should align it:
70 on 4 for 386
71 on 16 for 486
bb270c08
DB
72 on 32 for 586, PPro - k6-III
73 on 64 for K7 (maybe for P3 too).
d01fe86d
FB
74 Because L1 and L2 caches are aligned on those values.
75 But I don't want to code such logic here!
76 */
8f2b21a8 77 /* Why 16?
7ce68923 78 Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
8f2b21a8
MN
79 it will just trigger an exception and the unaligned load will be done in the
80 exception handler or it will just segfault (SSE2 on P4)
2cab6401 81 Why not larger? Because I did not see a difference in benchmarks ...
8f2b21a8
MN
82 */
83 /* benchmarks with p3
bb270c08
DB
84 memalign(64)+1 3071,3051,3032
85 memalign(64)+2 3051,3032,3041
86 memalign(64)+4 2911,2896,2915
87 memalign(64)+8 2545,2554,2550
88 memalign(64)+16 2543,2572,2563
89 memalign(64)+32 2546,2545,2571
90 memalign(64)+64 2570,2533,2558
115329f1 91
8f2b21a8
MN
92 btw, malloc seems to do 8 byte alignment by default here
93 */
d01fe86d
FB
94#else
95 ptr = malloc(size);
96#endif
d01fe86d
FB
97 return ptr;
98}
99
8e1e6f31
FB
100void *av_realloc(void *ptr, unsigned int size)
101{
b250f9c6 102#if CONFIG_MEMALIGN_HACK
0a7c36af
MN
103 int diff;
104#endif
88730be6 105
7d77d5f6 106 /* let's disallow possible ambiguous cases */
a9493601 107 if(size > (INT_MAX-16) )
0ecca7a4
MN
108 return NULL;
109
b250f9c6 110#if CONFIG_MEMALIGN_HACK
0a7c36af
MN
111 //FIXME this isn't aligned correctly, though it probably isn't needed
112 if(!ptr) return av_malloc(size);
113 diff= ((char*)ptr)[-1];
90d30570 114 return (char*)realloc((char*)ptr - diff, size + diff) + diff;
0a7c36af
MN
115#else
116 return realloc(ptr, size);
da9b170c 117#endif
b7a22d84
MN
118}
119
d01fe86d
FB
120void av_free(void *ptr)
121{
122 /* XXX: this test should not be needed on most libcs */
123 if (ptr)
b250f9c6 124#if CONFIG_MEMALIGN_HACK
90d30570 125 free((char*)ptr - ((char*)ptr)[-1]);
da9b170c 126#else
d01fe86d 127 free(ptr);
da9b170c 128#endif
d01fe86d
FB
129}
130
79e47000
LB
131void av_freep(void *arg)
132{
133 void **ptr= (void**)arg;
134 av_free(*ptr);
135 *ptr = NULL;
136}
137
138void *av_mallocz(unsigned int size)
139{
11362767 140 void *ptr = av_malloc(size);
79e47000
LB
141 if (ptr)
142 memset(ptr, 0, size);
143 return ptr;
144}
145
146char *av_strdup(const char *s)
147{
fdf35f26
MN
148 char *ptr= NULL;
149 if(s){
19757f61
MN
150 int len = strlen(s) + 1;
151 ptr = av_malloc(len);
152 if (ptr)
153 memcpy(ptr, s, len);
fdf35f26 154 }
79e47000
LB
155 return ptr;
156}
157