Do not #include common.h without necessity.
[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"
8e1e6f31 28
dfcb6b56 29#include <limits.h>
1f91cdce 30#include <stdlib.h>
dfcb6b56 31#include <string.h>
b250f9c6 32#if HAVE_MALLOC_H
d01fe86d
FB
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
18f77016 40void *av_malloc(unsigned int size)
d01fe86d 41{
1f91cdce 42 void *ptr = NULL;
b250f9c6 43#if CONFIG_MEMALIGN_HACK
ed96aeea 44 long diff;
88730be6 45#endif
0ecca7a4 46
7d77d5f6 47 /* let's disallow possible ambiguous cases */
0a7c36af 48 if(size > (INT_MAX-16) )
0ecca7a4 49 return NULL;
115329f1 50
b250f9c6 51#if CONFIG_MEMALIGN_HACK
a9493601
H
52 ptr = malloc(size+16);
53 if(!ptr)
54 return ptr;
ed96aeea 55 diff= ((-(long)ptr - 1)&15) + 1;
90d30570 56 ptr = (char*)ptr + diff;
da9b170c 57 ((char*)ptr)[-1]= diff;
b250f9c6 58#elif HAVE_POSIX_MEMALIGN
1f91cdce 59 posix_memalign(&ptr,16,size);
b250f9c6 60#elif HAVE_MEMALIGN
8f2b21a8 61 ptr = memalign(16,size);
115329f1 62 /* Why 64?
d01fe86d
FB
63 Indeed, we should align it:
64 on 4 for 386
65 on 16 for 486
bb270c08
DB
66 on 32 for 586, PPro - k6-III
67 on 64 for K7 (maybe for P3 too).
d01fe86d
FB
68 Because L1 and L2 caches are aligned on those values.
69 But I don't want to code such logic here!
70 */
8f2b21a8 71 /* Why 16?
7ce68923 72 Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
8f2b21a8
MN
73 it will just trigger an exception and the unaligned load will be done in the
74 exception handler or it will just segfault (SSE2 on P4)
2cab6401 75 Why not larger? Because I did not see a difference in benchmarks ...
8f2b21a8
MN
76 */
77 /* benchmarks with p3
bb270c08
DB
78 memalign(64)+1 3071,3051,3032
79 memalign(64)+2 3051,3032,3041
80 memalign(64)+4 2911,2896,2915
81 memalign(64)+8 2545,2554,2550
82 memalign(64)+16 2543,2572,2563
83 memalign(64)+32 2546,2545,2571
84 memalign(64)+64 2570,2533,2558
115329f1 85
8f2b21a8
MN
86 btw, malloc seems to do 8 byte alignment by default here
87 */
d01fe86d
FB
88#else
89 ptr = malloc(size);
90#endif
d01fe86d
FB
91 return ptr;
92}
93
8e1e6f31
FB
94void *av_realloc(void *ptr, unsigned int size)
95{
b250f9c6 96#if CONFIG_MEMALIGN_HACK
0a7c36af
MN
97 int diff;
98#endif
88730be6 99
7d77d5f6 100 /* let's disallow possible ambiguous cases */
a9493601 101 if(size > (INT_MAX-16) )
0ecca7a4
MN
102 return NULL;
103
b250f9c6 104#if CONFIG_MEMALIGN_HACK
0a7c36af
MN
105 //FIXME this isn't aligned correctly, though it probably isn't needed
106 if(!ptr) return av_malloc(size);
107 diff= ((char*)ptr)[-1];
90d30570 108 return (char*)realloc((char*)ptr - diff, size + diff) + diff;
0a7c36af
MN
109#else
110 return realloc(ptr, size);
da9b170c 111#endif
b7a22d84
MN
112}
113
d01fe86d
FB
114void av_free(void *ptr)
115{
116 /* XXX: this test should not be needed on most libcs */
117 if (ptr)
b250f9c6 118#if CONFIG_MEMALIGN_HACK
90d30570 119 free((char*)ptr - ((char*)ptr)[-1]);
da9b170c 120#else
d01fe86d 121 free(ptr);
da9b170c 122#endif
d01fe86d
FB
123}
124
79e47000
LB
125void av_freep(void *arg)
126{
127 void **ptr= (void**)arg;
128 av_free(*ptr);
129 *ptr = NULL;
130}
131
132void *av_mallocz(unsigned int size)
133{
11362767 134 void *ptr = av_malloc(size);
79e47000
LB
135 if (ptr)
136 memset(ptr, 0, size);
137 return ptr;
138}
139
140char *av_strdup(const char *s)
141{
fdf35f26
MN
142 char *ptr= NULL;
143 if(s){
19757f61
MN
144 int len = strlen(s) + 1;
145 ptr = av_malloc(len);
146 if (ptr)
147 memcpy(ptr, s, len);
fdf35f26 148 }
79e47000
LB
149 return ptr;
150}
151