1 | /*
|
---|
2 | * default memory allocator for libavcodec
|
---|
3 | * Copyright (c) 2002 Fabrice Bellard.
|
---|
4 | *
|
---|
5 | * This library is free software; you can redistribute it and/or
|
---|
6 | * modify it under the terms of the GNU Lesser General Public
|
---|
7 | * License as published by the Free Software Foundation; either
|
---|
8 | * version 2 of the License, or (at your option) any later version.
|
---|
9 | *
|
---|
10 | * This library is distributed in the hope that it will be useful,
|
---|
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
13 | * Lesser General Public License for more details.
|
---|
14 | *
|
---|
15 | * You should have received a copy of the GNU Lesser General Public
|
---|
16 | * License along with this library; if not, write to the Free Software
|
---|
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
---|
18 | */
|
---|
19 |
|
---|
20 | /**
|
---|
21 | * @file mem.c
|
---|
22 | * default memory allocator for libavcodec.
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "avcodec.h"
|
---|
26 |
|
---|
27 | /* here we can use OS dependant allocation functions */
|
---|
28 | #undef malloc
|
---|
29 | #undef free
|
---|
30 | #undef realloc
|
---|
31 |
|
---|
32 | #ifdef HAVE_MALLOC_H
|
---|
33 | #include <malloc.h>
|
---|
34 | #endif
|
---|
35 |
|
---|
36 | /* you can redefine av_malloc and av_free in your project to use your
|
---|
37 | memory allocator. You do not need to suppress this file because the
|
---|
38 | linker will do it automatically */
|
---|
39 |
|
---|
40 | /**
|
---|
41 | * Memory allocation of size byte with alignment suitable for all
|
---|
42 | * memory accesses (including vectors if available on the
|
---|
43 | * CPU). av_malloc(0) must return a non NULL pointer.
|
---|
44 | */
|
---|
45 | void *av_malloc(unsigned int size)
|
---|
46 | {
|
---|
47 | void *ptr;
|
---|
48 | #ifdef MEMALIGN_HACK
|
---|
49 | long diff;
|
---|
50 | #endif
|
---|
51 |
|
---|
52 | /* let's disallow possible ambiguous cases */
|
---|
53 | if(size > (INT_MAX-16) )
|
---|
54 | return NULL;
|
---|
55 |
|
---|
56 | #ifdef MEMALIGN_HACK
|
---|
57 | ptr = malloc(size+16);
|
---|
58 | if(!ptr)
|
---|
59 | return ptr;
|
---|
60 | diff= ((-(long)ptr - 1)&15) + 1;
|
---|
61 | ptr += diff;
|
---|
62 | ((char*)ptr)[-1]= diff;
|
---|
63 | #elif defined (HAVE_MEMALIGN)
|
---|
64 | ptr = memalign(16,size);
|
---|
65 | /* Why 64?
|
---|
66 | Indeed, we should align it:
|
---|
67 | on 4 for 386
|
---|
68 | on 16 for 486
|
---|
69 | on 32 for 586, PPro - k6-III
|
---|
70 | on 64 for K7 (maybe for P3 too).
|
---|
71 | Because L1 and L2 caches are aligned on those values.
|
---|
72 | But I don't want to code such logic here!
|
---|
73 | */
|
---|
74 | /* Why 16?
|
---|
75 | because some cpus need alignment, for example SSE2 on P4, & most RISC cpus
|
---|
76 | it will just trigger an exception and the unaligned load will be done in the
|
---|
77 | exception handler or it will just segfault (SSE2 on P4)
|
---|
78 | Why not larger? because i didnt see a difference in benchmarks ...
|
---|
79 | */
|
---|
80 | /* benchmarks with p3
|
---|
81 | memalign(64)+1 3071,3051,3032
|
---|
82 | memalign(64)+2 3051,3032,3041
|
---|
83 | memalign(64)+4 2911,2896,2915
|
---|
84 | memalign(64)+8 2545,2554,2550
|
---|
85 | memalign(64)+16 2543,2572,2563
|
---|
86 | memalign(64)+32 2546,2545,2571
|
---|
87 | memalign(64)+64 2570,2533,2558
|
---|
88 |
|
---|
89 | btw, malloc seems to do 8 byte alignment by default here
|
---|
90 | */
|
---|
91 | #else
|
---|
92 | ptr = malloc(size);
|
---|
93 | #endif
|
---|
94 | return ptr;
|
---|
95 | }
|
---|
96 |
|
---|
97 | /**
|
---|
98 | * av_realloc semantics (same as glibc): if ptr is NULL and size > 0,
|
---|
99 | * identical to malloc(size). If size is zero, it is identical to
|
---|
100 | * free(ptr) and NULL is returned.
|
---|
101 | */
|
---|
102 | void *av_realloc(void *ptr, unsigned int size)
|
---|
103 | {
|
---|
104 | #ifdef MEMALIGN_HACK
|
---|
105 | int diff;
|
---|
106 | #endif
|
---|
107 |
|
---|
108 | /* let's disallow possible ambiguous cases */
|
---|
109 | if(size > (INT_MAX-16) )
|
---|
110 | return NULL;
|
---|
111 |
|
---|
112 | #ifdef MEMALIGN_HACK
|
---|
113 | //FIXME this isn't aligned correctly, though it probably isn't needed
|
---|
114 | if(!ptr) return av_malloc(size);
|
---|
115 | diff= ((char*)ptr)[-1];
|
---|
116 | return realloc(ptr - diff, size + diff) + diff;
|
---|
117 | #else
|
---|
118 | return realloc(ptr, size);
|
---|
119 | #endif
|
---|
120 | }
|
---|
121 |
|
---|
122 | /**
|
---|
123 | * Free memory which has been allocated with av_malloc(z)() or av_realloc().
|
---|
124 | * NOTE: ptr = NULL is explicetly allowed
|
---|
125 | * Note2: it is recommended that you use av_freep() instead
|
---|
126 | */
|
---|
127 | void av_free(void *ptr)
|
---|
128 | {
|
---|
129 | /* XXX: this test should not be needed on most libcs */
|
---|
130 | if (ptr)
|
---|
131 | #ifdef MEMALIGN_HACK
|
---|
132 | free(ptr - ((char*)ptr)[-1]);
|
---|
133 | #else
|
---|
134 | free(ptr);
|
---|
135 | #endif
|
---|
136 | }
|
---|
137 |
|
---|