|
808
|
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 mem.c
|
|
|
24 * default memory allocator for libavutil.
|
|
|
25 */
|
|
|
26
|
|
|
27 #include "common.h"
|
|
|
28
|
|
|
29 /* here we can use OS dependant allocation functions */
|
|
|
30 #undef malloc
|
|
|
31 #undef free
|
|
|
32 #undef realloc
|
|
|
33
|
|
|
34 #ifdef HAVE_MALLOC_H
|
|
|
35 #include <malloc.h>
|
|
|
36 #endif
|
|
|
37
|
|
|
38 /* you can redefine av_malloc and av_free in your project to use your
|
|
|
39 memory allocator. You do not need to suppress this file because the
|
|
|
40 linker will do it automatically */
|
|
|
41
|
|
|
42 /**
|
|
|
43 * Memory allocation of size byte with alignment suitable for all
|
|
|
44 * memory accesses (including vectors if available on the
|
|
|
45 * CPU). av_malloc(0) must return a non NULL pointer.
|
|
|
46 */
|
|
|
47 void *av_malloc(unsigned int size)
|
|
|
48 {
|
|
|
49 void *ptr;
|
|
|
50 #ifdef MEMALIGN_HACK
|
|
|
51 long diff;
|
|
|
52 #endif
|
|
|
53
|
|
|
54 /* let's disallow possible ambiguous cases */
|
|
|
55 if(size > (INT_MAX-16) )
|
|
|
56 return NULL;
|
|
|
57
|
|
|
58 #ifdef MEMALIGN_HACK
|
|
|
59 ptr = malloc(size+16);
|
|
|
60 if(!ptr)
|
|
|
61 return ptr;
|
|
|
62 diff= ((-(long)ptr - 1)&15) + 1;
|
|
|
63 ptr += diff;
|
|
|
64 ((char*)ptr)[-1]= diff;
|
|
|
65 #elif defined (HAVE_MEMALIGN)
|
|
|
66 ptr = memalign(16,size);
|
|
|
67 /* Why 64?
|
|
|
68 Indeed, we should align it:
|
|
|
69 on 4 for 386
|
|
|
70 on 16 for 486
|
|
|
71 on 32 for 586, PPro - k6-III
|
|
|
72 on 64 for K7 (maybe for P3 too).
|
|
|
73 Because L1 and L2 caches are aligned on those values.
|
|
|
74 But I don't want to code such logic here!
|
|
|
75 */
|
|
|
76 /* Why 16?
|
|
|
77 because some cpus need alignment, for example SSE2 on P4, & most RISC cpus
|
|
|
78 it will just trigger an exception and the unaligned load will be done in the
|
|
|
79 exception handler or it will just segfault (SSE2 on P4)
|
|
|
80 Why not larger? because i didnt see a difference in benchmarks ...
|
|
|
81 */
|
|
|
82 /* benchmarks with p3
|
|
|
83 memalign(64)+1 3071,3051,3032
|
|
|
84 memalign(64)+2 3051,3032,3041
|
|
|
85 memalign(64)+4 2911,2896,2915
|
|
|
86 memalign(64)+8 2545,2554,2550
|
|
|
87 memalign(64)+16 2543,2572,2563
|
|
|
88 memalign(64)+32 2546,2545,2571
|
|
|
89 memalign(64)+64 2570,2533,2558
|
|
|
90
|
|
|
91 btw, malloc seems to do 8 byte alignment by default here
|
|
|
92 */
|
|
|
93 #else
|
|
|
94 ptr = malloc(size);
|
|
|
95 #endif
|
|
|
96 return ptr;
|
|
|
97 }
|
|
|
98
|
|
|
99 /**
|
|
|
100 * av_realloc semantics (same as glibc): if ptr is NULL and size > 0,
|
|
|
101 * identical to malloc(size). If size is zero, it is identical to
|
|
|
102 * free(ptr) and NULL is returned.
|
|
|
103 */
|
|
|
104 void *av_realloc(void *ptr, unsigned int size)
|
|
|
105 {
|
|
|
106 #ifdef MEMALIGN_HACK
|
|
|
107 int diff;
|
|
|
108 #endif
|
|
|
109
|
|
|
110 /* let's disallow possible ambiguous cases */
|
|
|
111 if(size > (INT_MAX-16) )
|
|
|
112 return NULL;
|
|
|
113
|
|
|
114 #ifdef MEMALIGN_HACK
|
|
|
115 //FIXME this isn't aligned correctly, though it probably isn't needed
|
|
|
116 if(!ptr) return av_malloc(size);
|
|
|
117 diff= ((char*)ptr)[-1];
|
|
|
118 return realloc(ptr - diff, size + diff) + diff;
|
|
|
119 #else
|
|
|
120 return realloc(ptr, size);
|
|
|
121 #endif
|
|
|
122 }
|
|
|
123
|
|
|
124 /**
|
|
|
125 * Free memory which has been allocated with av_malloc(z)() or av_realloc().
|
|
|
126 * NOTE: ptr = NULL is explicetly allowed
|
|
|
127 * Note2: it is recommended that you use av_freep() instead
|
|
|
128 */
|
|
|
129 void av_free(void *ptr)
|
|
|
130 {
|
|
|
131 /* XXX: this test should not be needed on most libcs */
|
|
|
132 if (ptr)
|
|
|
133 #ifdef MEMALIGN_HACK
|
|
|
134 free(ptr - ((char*)ptr)[-1]);
|
|
|
135 #else
|
|
|
136 free(ptr);
|
|
|
137 #endif
|
|
|
138 }
|
|
|
139
|
|
|
140 /**
|
|
|
141 * Frees memory and sets the pointer to NULL.
|
|
|
142 * @param arg pointer to the pointer which should be freed
|
|
|
143 */
|
|
|
144 void av_freep(void *arg)
|
|
|
145 {
|
|
|
146 void **ptr= (void**)arg;
|
|
|
147 av_free(*ptr);
|
|
|
148 *ptr = NULL;
|
|
|
149 }
|
|
|
150
|
|
|
151 void *av_mallocz(unsigned int size)
|
|
|
152 {
|
|
|
153 void *ptr;
|
|
|
154
|
|
|
155 ptr = av_malloc(size);
|
|
|
156 if (ptr)
|
|
|
157 memset(ptr, 0, size);
|
|
|
158 return ptr;
|
|
|
159 }
|
|
|
160
|
|
|
161 char *av_strdup(const char *s)
|
|
|
162 {
|
|
|
163 char *ptr;
|
|
|
164 int len;
|
|
|
165 len = strlen(s) + 1;
|
|
|
166 ptr = av_malloc(len);
|
|
|
167 if (ptr)
|
|
|
168 memcpy(ptr, s, len);
|
|
|
169 return ptr;
|
|
|
170 }
|
|
|
171
|