Statistics
| Branch: | Revision:

ffmpeg / libavutil / mem.c @ 91ff05f6

History | View | Annotate | Download (4.8 KB)

1 d01fe86d Fabrice Bellard
/*
2 cea8f6f3 Luca Abeni
 * default memory allocator for libavutil
3 406792e7 Diego Biurrun
 * Copyright (c) 2002 Fabrice Bellard
4 d01fe86d Fabrice Bellard
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 d01fe86d Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 d01fe86d Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 d01fe86d Fabrice Bellard
 * 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 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 d01fe86d Fabrice Bellard
 */
21 115329f1 Diego Biurrun
22 983e3246 Michael Niedermayer
/**
23 ba87f080 Diego Biurrun
 * @file
24 89c9ff50 Diego Biurrun
 * default memory allocator for libavutil
25 983e3246 Michael Niedermayer
 */
26 115329f1 Diego Biurrun
27 dfcb6b56 Diego Biurrun
#include "config.h"
28 8e1e6f31 Fabrice Bellard
29 dfcb6b56 Diego Biurrun
#include <limits.h>
30 1f91cdce Ramiro Polla
#include <stdlib.h>
31 dfcb6b56 Diego Biurrun
#include <string.h>
32 b250f9c6 Aurelien Jacobs
#if HAVE_MALLOC_H
33 d01fe86d Fabrice Bellard
#include <malloc.h>
34
#endif
35
36 4ae40685 Måns Rullgård
#include "avutil.h"
37 77652a6a Diego Biurrun
#include "mem.h"
38
39 89c9ff50 Diego Biurrun
/* here we can use OS-dependent allocation functions */
40 1e60e933 Diego Biurrun
#undef free
41
#undef malloc
42
#undef realloc
43
44 4ae40685 Måns Rullgård
#ifdef MALLOC_PREFIX
45
46
#define malloc         AV_JOIN(MALLOC_PREFIX, malloc)
47
#define memalign       AV_JOIN(MALLOC_PREFIX, memalign)
48
#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
49
#define realloc        AV_JOIN(MALLOC_PREFIX, realloc)
50
#define free           AV_JOIN(MALLOC_PREFIX, free)
51
52
void *malloc(size_t size);
53
void *memalign(size_t align, size_t size);
54
int   posix_memalign(void **ptr, size_t align, size_t size);
55
void *realloc(void *ptr, size_t size);
56
void  free(void *ptr);
57
58
#endif /* MALLOC_PREFIX */
59
60 89c9ff50 Diego Biurrun
/* You can redefine av_malloc and av_free in your project to use your
61 d01fe86d Fabrice Bellard
   memory allocator. You do not need to suppress this file because the
62 89c9ff50 Diego Biurrun
   linker will do it automatically. */
63 d01fe86d Fabrice Bellard
64 490a022d Anton Khirnov
void *av_malloc(size_t size)
65 d01fe86d Fabrice Bellard
{
66 1f91cdce Ramiro Polla
    void *ptr = NULL;
67 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
68 ed96aeea Dieter
    long diff;
69 88730be6 Måns Rullgård
#endif
70 0ecca7a4 Michael Niedermayer
71 7d77d5f6 Diego Biurrun
    /* let's disallow possible ambiguous cases */
72 13dfce3d Vitor Sessak
    if(size > (INT_MAX-32) )
73 0ecca7a4 Michael Niedermayer
        return NULL;
74 5a36783b Michael Niedermayer
    else if(!size)
75
        size= 1;
76 115329f1 Diego Biurrun
77 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
78 13dfce3d Vitor Sessak
    ptr = malloc(size+32);
79 a9493601 Herve W
    if(!ptr)
80
        return ptr;
81 13dfce3d Vitor Sessak
    diff= ((-(long)ptr - 1)&31) + 1;
82 90d30570 avcoder
    ptr = (char*)ptr + diff;
83 da9b170c Michael Niedermayer
    ((char*)ptr)[-1]= diff;
84 b250f9c6 Aurelien Jacobs
#elif HAVE_POSIX_MEMALIGN
85 13dfce3d Vitor Sessak
    if (posix_memalign(&ptr,32,size))
86 a90de11d Patrik Kullman
        ptr = NULL;
87 b250f9c6 Aurelien Jacobs
#elif HAVE_MEMALIGN
88 13dfce3d Vitor Sessak
    ptr = memalign(32,size);
89 115329f1 Diego Biurrun
    /* Why 64?
90 d01fe86d Fabrice Bellard
       Indeed, we should align it:
91
         on 4 for 386
92
         on 16 for 486
93 89c9ff50 Diego Biurrun
         on 32 for 586, PPro - K6-III
94 bb270c08 Diego Biurrun
         on 64 for K7 (maybe for P3 too).
95 d01fe86d Fabrice Bellard
       Because L1 and L2 caches are aligned on those values.
96
       But I don't want to code such logic here!
97
     */
98 13dfce3d Vitor Sessak
     /* Why 32?
99
        For AVX ASM. SSE / NEON needs only 16.
100 2cab6401 Diego Biurrun
        Why not larger? Because I did not see a difference in benchmarks ...
101 8f2b21a8 Michael Niedermayer
     */
102 89c9ff50 Diego Biurrun
     /* benchmarks with P3
103 bb270c08 Diego Biurrun
        memalign(64)+1          3071,3051,3032
104
        memalign(64)+2          3051,3032,3041
105
        memalign(64)+4          2911,2896,2915
106
        memalign(64)+8          2545,2554,2550
107
        memalign(64)+16         2543,2572,2563
108
        memalign(64)+32         2546,2545,2571
109
        memalign(64)+64         2570,2533,2558
110 115329f1 Diego Biurrun

111 89c9ff50 Diego Biurrun
        BTW, malloc seems to do 8-byte alignment by default here.
112 8f2b21a8 Michael Niedermayer
     */
113 d01fe86d Fabrice Bellard
#else
114
    ptr = malloc(size);
115
#endif
116
    return ptr;
117
}
118
119 490a022d Anton Khirnov
void *av_realloc(void *ptr, size_t size)
120 8e1e6f31 Fabrice Bellard
{
121 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
122 0a7c36af Michael Niedermayer
    int diff;
123
#endif
124 88730be6 Måns Rullgård
125 7d77d5f6 Diego Biurrun
    /* let's disallow possible ambiguous cases */
126 a9493601 Herve W
    if(size > (INT_MAX-16) )
127 0ecca7a4 Michael Niedermayer
        return NULL;
128
129 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
130 0a7c36af Michael Niedermayer
    //FIXME this isn't aligned correctly, though it probably isn't needed
131
    if(!ptr) return av_malloc(size);
132
    diff= ((char*)ptr)[-1];
133 90d30570 avcoder
    return (char*)realloc((char*)ptr - diff, size + diff) + diff;
134 0a7c36af Michael Niedermayer
#else
135 91ff05f6 Michael Niedermayer
    return realloc(ptr, size + !size);
136 da9b170c Michael Niedermayer
#endif
137 b7a22d84 Michael Niedermayer
}
138
139 d01fe86d Fabrice Bellard
void av_free(void *ptr)
140
{
141 b250f9c6 Aurelien Jacobs
#if CONFIG_MEMALIGN_HACK
142 0c8eb72e Clément Bœsch
    if (ptr)
143 90d30570 avcoder
        free((char*)ptr - ((char*)ptr)[-1]);
144 da9b170c Michael Niedermayer
#else
145 0c8eb72e Clément Bœsch
    free(ptr);
146 da9b170c Michael Niedermayer
#endif
147 d01fe86d Fabrice Bellard
}
148
149 79e47000 Luca Barbato
void av_freep(void *arg)
150
{
151
    void **ptr= (void**)arg;
152
    av_free(*ptr);
153
    *ptr = NULL;
154
}
155
156 490a022d Anton Khirnov
void *av_mallocz(size_t size)
157 79e47000 Luca Barbato
{
158 11362767 Michael Niedermayer
    void *ptr = av_malloc(size);
159 79e47000 Luca Barbato
    if (ptr)
160
        memset(ptr, 0, size);
161
    return ptr;
162
}
163
164
char *av_strdup(const char *s)
165
{
166 fdf35f26 Michael Niedermayer
    char *ptr= NULL;
167
    if(s){
168 19757f61 Michael Niedermayer
        int len = strlen(s) + 1;
169
        ptr = av_malloc(len);
170
        if (ptr)
171
            memcpy(ptr, s, len);
172 fdf35f26 Michael Niedermayer
    }
173 79e47000 Luca Barbato
    return ptr;
174
}
175
176 35ceaa73 Anton Khirnov
/* add one element to a dynamic array */
177
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
178
{
179
    /* see similar ffmpeg.c:grow_array() */
180
    int nb, nb_alloc;
181
    intptr_t *tab;
182
183
    nb = *nb_ptr;
184
    tab = *(intptr_t**)tab_ptr;
185
    if ((nb & (nb - 1)) == 0) {
186
        if (nb == 0)
187
            nb_alloc = 1;
188
        else
189
            nb_alloc = nb * 2;
190
        tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
191
        *(intptr_t**)tab_ptr = tab;
192
    }
193
    tab[nb++] = (intptr_t)elem;
194
    *nb_ptr = nb;
195
}